package com.xbongbong.paas.print.helper;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.enums.VisibleTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.LinkedAttrPoJo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.field.VisibleRulePoJo;
import com.xbongbong.paas.field.VisibleRuleVO;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.PrintSubFromDataGetDTO;
import com.xbongbong.paas.pojo.dto.ProcessNodeTaskGetDTO;
import com.xbongbong.paas.pojo.dto.WorkOrderV2FixDataDTO;
import com.xbongbong.paas.pojo.vo.FormDataGetVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.pojo.vo.ProcessNodeTaskGetVO;
import com.xbongbong.paas.print.enums.AdditionalPrintAttrEnum;
import com.xbongbong.paas.print.manager.feign.FormFeignClient;
import com.xbongbong.paas.print.manager.feign.WorkOrderPrintClient;
import com.xbongbong.paas.print.manager.feign.WorkOrderV2FixDataFeignClient;
import com.xbongbong.paas.print.pojo.ProcessTaskIdPojo;
import com.xbongbong.paas.print.pojo.dto.PaasPrintGetDataByProcessDTO;
import com.xbongbong.paas.print.pojo.dto.PaasPrintGetDataDTO;
import com.xbongbong.paas.print.pojo.dto.PaasPrintGetDatasByProcessDTO;
import com.xbongbong.paas.print.pojo.dto.PaasPrintGetDatasDTO;
import com.xbongbong.paas.print.pojo.vo.PrintGetDataVO;
import com.xbongbong.paas.print.pojo.vo.WorkOrderV2FixDataVO;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.MoneyUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.PrintConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.customerstatement.pojo.StatementTableDataExportPojo;
import com.xbongbong.pro.customerstatement.pojo.dto.StatementCustomerSummaryDTO;
import com.xbongbong.pro.customerstatement.pojo.dto.StatementCustomerTableDTO;
import com.xbongbong.pro.customerstatement.pojo.dto.StatementSummaryDetailDTO;
import com.xbongbong.pro.customerstatement.pojo.vo.StatementCustomerTableVO;
import com.xbongbong.pro.customerstatement.pojo.vo.StatementSummaryDetailVO;
import com.xbongbong.pro.detailtab.dto.DetailTabDataGetDTO;
import com.xbongbong.pro.detailtab.dto.PrintDataVisibleDTO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.PrintInvoicePurchaseTotalMoneyEnum;
import com.xbongbong.pro.enums.PrintInvoiceTotalMoneyEnum;
import com.xbongbong.pro.enums.PrintPaySheetAmountEnum;
import com.xbongbong.pro.enums.PrintPaymentSheetAmountEnum;
import com.xbongbong.pro.enums.PrintSpecialAttrEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.StatisticOptionEnum;
import com.xbongbong.pro.enums.errorcodes.ApprovalErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.StatementErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.PayMethodDistributorEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.invoice.pojo.dto.InvoiceAmountDetailDTO;
import com.xbongbong.pro.pojo.dto.PaasConfigGetDTO;
import com.xbongbong.pro.pojo.vo.PaasConfigGetVO;
import com.xbongbong.pro.product.pojo.vo.RelationProductListVO;
import com.xbongbong.pro.service.toolbox.subform.PaasConfigService;
import com.xbongbong.pro.webdetail.pojo.WorkReportDetailStatisticResultPojo;
import com.xbongbong.pro.webdetail.pojo.vo.WorkReportDetailVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.MultiUnitConstant;
import com.xbongbong.saas.constant.OnlineEditorConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StockConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.WarehouseUserEntity;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.SupplierEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderExplainEntityExt;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.CustomerInvoiceEnum;
import com.xbongbong.saas.enums.CustomerStatementEnum;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.InvoiceTitleTypeEnum;
import com.xbongbong.saas.enums.OutstockSaleRelativeConstantEnum;
import com.xbongbong.saas.enums.PrintTemplateTypeEnum;
import com.xbongbong.saas.enums.ProductPrintHelpEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RelativeProductEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.ServicePrintHelpEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.PaymentSheetBaseEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.ContractOutstockEnum;
import com.xbongbong.saas.enums.business.CostAdjustEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.ReceiptOrderEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.enums.business.WaitOutstockEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.business.WorkReportDailyEnum;
import com.xbongbong.saas.enums.business.WorkReportPlanEnum;
import com.xbongbong.saas.enums.product.CostAdjustProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.model.BomUserModel;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.model.ProductionOrderUserModel;
import com.xbongbong.saas.model.SupplierModel;
import com.xbongbong.saas.model.SupplierUserModel;
import com.xbongbong.saas.model.WarehouseUserModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.paas.constant.MessageConstant.PROCESS_DATA_NOT_EXIST;


/** 打印帮助类
 * @author zheng.li
 * @version v1.0
 * @date 2019/3/12 10:44
 * @since v1.0
 */
@Service
public class PrintHelper {

    @Resource
    private FormFeignClient formFeignClient;
    @Resource
    private SupplierModel supplierModel;
    @Resource
    private SupplierUserModel supplierUserModel;
    @Resource
    private BomUserModel bomUserModel;
    @Resource
    private ProductionOrderUserModel productionOrderUserModel;
    @Resource
    private WarehouseUserModel warehouseUserModel;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private ContactModel contactModel;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaasConfigService paasConfigService;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private WorkOrderPrintClient workOrderPrintClient;
    @Resource
    private WorkOrderV2FixDataFeignClient workOrderV2FixDataFeignClient;


    private static final Logger LOG = LoggerFactory.getLogger(PrintHelper.class);


    /**
     * 获取对应数据
     *
     * @param loginUser   员工信息
     * @param paasPrintGetDataDTO  前端传参
     * @return data
     */
    public JSONArray getValue(UserVO loginUser, PaasPrintGetDataDTO paasPrintGetDataDTO, PaasFormEntity paasFormEntity) throws XbbException{
        Integer businessType = paasPrintGetDataDTO.getBusinessType();
        Long entityId = paasPrintGetDataDTO.getEntityId();
        JSONArray valueArray = new JSONArray();

        FormDataGetDTO formDataGetDTO = new FormDataGetDTO();
        BeanUtil.copyProperties(paasPrintGetDataDTO,formDataGetDTO);
        formDataGetDTO.setMenuId(paasFormEntity.getMenuId());
        formDataGetDTO.setSaasMark(paasFormEntity.getSaasMark());
        formDataGetDTO.setAppId(paasFormEntity.getAppId());
        formDataGetDTO.setDataId(entityId);
        return getEntityValues(paasFormEntity, loginUser, businessType, entityId, valueArray,formDataGetDTO);
    }

    /**
     * 批量获取对应数据
     *
     * @param loginUser   员工信息
     * @param paasPrintGetDatasDTO  前端传参
     * @return data
     */
    public JSONArray getValues(UserVO loginUser, PaasPrintGetDatasDTO paasPrintGetDatasDTO, PaasFormEntity paasFormEntity) throws XbbException{
        Integer businessType = paasPrintGetDatasDTO.getBusinessType();
        List<Long> entityIds = paasPrintGetDatasDTO.getEntityIds();
        JSONArray valueArray = new JSONArray();
        FormDataGetDTO formDataGetDTO = new FormDataGetDTO();
        BeanUtil.copyProperties(paasPrintGetDatasDTO,formDataGetDTO);
        formDataGetDTO.setMenuId(paasFormEntity.getMenuId());
        formDataGetDTO.setSaasMark(paasFormEntity.getSaasMark());
        formDataGetDTO.setAppId(paasFormEntity.getAppId());
        for (Long entityId : entityIds) {
            formDataGetDTO.setDataId(entityId);
            getEntityValues(paasFormEntity, loginUser, businessType, entityId, valueArray,formDataGetDTO);
        }
        return valueArray;
    }

    /**
     * 获取实体值
     * @param paasFormEntity 表单实体
     * @param loginUser 当前用户
     * @param businessType 业务类型
     * @param entityId 实体id
     * @param valueArray 返回值
     * @return 数组
     * @throws XbbException XbbException
     */
    private JSONArray getEntityValues(PaasFormEntity paasFormEntity, UserVO loginUser, Integer businessType, Long entityId, JSONArray valueArray,FormDataGetDTO formDataGetDTO) throws XbbException {
        PrintTemplateTypeEnum printTemplateTypeEnum = PrintTemplateTypeEnum.getByCode(businessType);
        String corpid = loginUser.getCorpid();
        // 获取表单数据基本信息
        boolean isWorkReport = Objects.equals(XbbRefTypeEnum.WORK_REPORT.getCode(),businessType);
        if (isWorkReport) {
            // 工作报告subBusinessType
            formDataGetDTO.setSubBusinessType(paasFormEntity.getBusinessType());
        }
        String dataResult;
        WorkReportDetailVO workReportDetailVO = null;
        String workOrderDynamic = null;
        String workOrderProcess = null;
        PrintGetDataVO printGetDataVO = new PrintGetDataVO();
        try {
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            // 如果业务是客户对账单，那么需要走特殊逻辑
            if (businessType.equals(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode()) || businessType.equals(XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode())) {
                formDataGetDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
            }
            formDataGetDTO.setIsPrint(1);
            if (Objects.equals(XbbRefTypeEnum.RECEIPT_ORDER.getCode(),businessType) || Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2.getCode(),businessType)) {
                dataResult = workOrderPrintClient.getFormData(formDataGetDTO, lang);
            } else {
                dataResult = formFeignClient.getFormData(formDataGetDTO, lang);
            }
            if (isWorkReport){
                String workReportData = formFeignClient.workReportDetail(formDataGetDTO, lang);
                JSONObject resultObj = JsonHelperUtil.parseObject(workReportData);
                if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
                    throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
                }
                workReportDetailVO = JsonHelperUtil.parseObject(resultObj.getString("result"),WorkReportDetailVO.class);
                if (workReportDetailVO == null || workReportDetailVO.getStatisticResultList().size() == 0){
                    // 表单数据不存在，直接返回
                    valueArray.add(printGetDataVO);
                    return valueArray;
                }
            }
            if(Objects.equals(businessType,XbbRefTypeEnum.WORK_ORDER.getCode())){
                // 获取工单进展
                workOrderProcess = formFeignClient.getPrintRelationData(formDataGetDTO,lang);
                // 获取工单动态
                workOrderDynamic = formFeignClient.getPrintDynamicData(formDataGetDTO,lang);
            }
        } catch (Exception e) {
            LOG.error("获取表单数据报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nStringConstant.FORM_DATA_ERROR);
        }

        JSONObject resultObj = JsonHelperUtil.parseObject(dataResult);
        if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
            throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
        }
        FormDataGetVO formDataGetVO = JsonHelperUtil.parseObject(resultObj.getString("result"),FormDataGetVO.class);
        JSONObject data = formDataGetVO.getData();
        if(data == null){
            // 表单数据不存在，直接返回
            valueArray.add(printGetDataVO);
            return valueArray;
        }

        Map<String, FieldAttrEntity> explainMap ;
        List<FieldAttrEntity> fieldAttrEntities ;
        Long formId = formDataGetDTO.getFormId();
        PaasFormExplainEntity paasFormExplainEntity = null;
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt byFormId = workOrderExplainModel.getByFormId(formId, corpid);
            explainMap = ExplainUtil.getExplainMap(byFormId.getExplains(), null);
            fieldAttrEntities  = JsonHelperUtil.parseArray(byFormId.getExplains(),FieldAttrEntity.class);
            if (byFormId == null) {
                // 字段解释不存在，直接返回
                valueArray.add(printGetDataVO);
                return valueArray;
            }
        } else {
            paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
            fieldAttrEntities  = JsonHelperUtil.parseArray(paasFormExplainEntity.getExplains(),FieldAttrEntity.class);
            if (paasFormExplainEntity == null) {
                // 字段解释不存在，直接返回
                valueArray.add(printGetDataVO);
                return valueArray;
            }
        }
        // explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        // fieldAttrEntities  = JsonHelperUtil.parseArray(paasFormExplainEntity.getExplains(),FieldAttrEntity.class);

        // 要返回的新data数据
        JSONObject newData = new JSONObject();
        newData.putAll(data);


        try {
            // 17707 【打印】自定义表单限制字段权限后，打印模板中仍可看到该字段的值
            if (Objects.equals(businessType, 0)) {
                PaasFormDataEntityExt paasFormDataEntity = paasFormDataModel.getByKey(entityId, corpid);
                HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                BeanUtil.copyProperties(formDataGetDTO, handlerExplainDTO);
                handlerExplainDTO.setCreatorId(paasFormDataEntity.getCreatorId());
                handlerExplainDTO.setOwnerId(Arrays.asList(paasFormDataEntity.getOwnerId()));
                handlerExplainDTO.setExplainList(new ArrayList<>(explainMap.values()));
                handlerExplainDTO.setPaasFormEntityExt((PaasFormEntityExt) paasFormEntity);
                for (String attr : data.keySet()) {
                    if (explainMap.containsKey(attr) && Objects.nonNull(explainMap.get(attr))) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                        if (!ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())
                                && (ExplainUtil.invisibleOfScope(fieldAttrEntity, handlerExplainDTO) || Objects.equals(fieldAttrEntity.getIsOpen(), 2))) {
                            newData.remove(attr);
                        } else if (ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                            // 子表单相关数据
                            Map<String, FieldAttrEntity> subFieldMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainMap.get(attr).getSubForm().getItems()), null);
                            JSONArray jsonArray = newData.getJSONArray(attr);
                            if (Objects.nonNull(jsonArray)) {
                                for (int i = 0; i < jsonArray.size(); i++) {
                                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                                    if (Objects.nonNull(jsonObject)) {
                                        Iterator<String> object = jsonObject.keySet().iterator();
                                        while (object.hasNext()){
                                            String subAttr = object.next();
                                            FieldAttrEntity subField = subFieldMap.get(subAttr);
                                            if (Objects.nonNull(subField) && Objects.equals(subField.getIsOpen(), 2)) {
                                                object.remove();
                                                continue;
                                            }
                                            if (Objects.nonNull(subField) && ExplainUtil.invisibleOfScope(subField, handlerExplainDTO)) {
                                                jsonObject.put(subAttr, "******");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            LOG.error("打印报错：", e);
        }

        // 字段类型：(多行文本字段列表)
        JSONObject attrInfo = new JSONObject();
        getAttrInfo(fieldAttrEntities, attrInfo);
        // 调整字段数据值（有些数组要转成String）
        JSONObject dataLinkInfo = new JSONObject();
        adjustAttrValue(formDataGetVO.getHeadList(), newData, fieldAttrEntities, dataLinkInfo, loginUser);
        // 过滤关联数据未选择的值
        filterLinkDataForNoChoose(newData, fieldAttrEntities);
        // 标签字段值设置
        filterLabelData(newData, fieldAttrEntities);
        dealTemplateField(newData,fieldAttrEntities);
        // 制表人和打印日期
        newData.put(AdditionalPrintAttrEnum.TABLE_MAKER.getAttr(),loginUser.getName());
        newData.put(AdditionalPrintAttrEnum.PRINT_DATE_TIME.getAttr(),DateTimeUtil.getDateStringEpochSecond(DateTimeUtil.getInt()));

        JSONArray amountDetail = formDataGetVO.getAmountDetail();
        String printFundType;
        switch (printTemplateTypeEnum) {
            case CONTRACT:
                // 客户地址和客户电话
                addCustomerAddressPhone(corpid, data,newData);
                // 联系人电话
                addContactPhone(corpid,data,newData);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ContractEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData,ContractEnum.PRODUCT.getAttr(), XbbRefTypeEnum.CONTRACT.getCode(), explainMap);
                // 部分字段未启用或不可见的处理
                setHideWithAttr(formDataGetDTO, explainMap, data, newData);

                break;
            case QUOTATION:
                // 客户地址和客户电话
                customerPhoneAddress(corpid, data,newData);
                // 联系人地址和电话
                contactPhoneAddress(corpid,data,newData);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(QuotationEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData,QuotationEnum.PRODUCT.getAttr(), XbbRefTypeEnum.QUOTATION.getCode(), explainMap);
                // 部分字段未启用或不可见的处理
                setHideWithAttr(formDataGetDTO, explainMap, data, newData);
                break;
            case SALES_OPPORTUNITY:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(SalesOpportunityEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData,SalesOpportunityEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), explainMap);
                // 部分字段未启用或不可见的处理
                setHideWithAttr(formDataGetDTO, explainMap, data, newData);
                break;
            case WORKREPORT:
                setWorkReportStatisticAttr(data,newData, WorkReportDailyEnum.THIS_STATISTIC.getAttr(), workReportDetailVO);
                setHideWithAttr(formDataGetDTO, explainMap, data, newData);
                break;
            case REFUND:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(RefundEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 退货产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, RefundEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.REFUND.getCode(), explainMap);
                break;
            case PURCHASE:
                addSupplierData(corpid,data,newData,PurchaseEnum.SUPPLIER_ID.getAttr(),formDataGetDTO);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(PurchaseEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData,PurchaseEnum.PRODUCT.getAttr(), XbbRefTypeEnum.PURCHASE.getCode(), explainMap);
                break;
            case RETURNED_PURCHASE:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ReturnedPurchaseEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, ReturnedPurchaseEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), explainMap);
                // 供应商相关
                addSupplierData(corpid,data,newData, ReturnedPurchaseEnum.SUPPLIER_ID.getAttr(),formDataGetDTO);
                break;
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case OTHER_INSTOCK:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(InstockEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, InstockEnum.PRODUCT.getAttr(), XbbRefTypeEnum.INSTOCK.getCode(), explainMap);
                // 23940 【WEB-其他入库单】打印界面“业务类型”为其他入库时，关联单据值回显优化
                if (Objects.equals(businessType, PrintTemplateTypeEnum.OTHER_INSTOCK.getCode())) {
                    String type = newData.getString(InstockEnum.TYPE.getAttr());
                    if (Objects.equals(type, InstockTypeEnum.OTHER_INSTOCK.getName())) {
                        newData.put(InstockEnum.REF_ID.getAttr(), I18nMessageUtil.getMessage(CommonConstant.NOTHING));
                    }
                }
                break;
            case CONTRACT_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case OUTSTOCK:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(OutstockEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, OutstockEnum.PRODUCT.getAttr(), printTemplateTypeEnum.getCode(), explainMap);
                break;
            case INVENTORY:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(InventoryEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, InventoryEnum.PRODUCT.getAttr(), XbbRefTypeEnum.INVENTORY.getCode(), explainMap);
                // 部分字段未启用或不可见的处理
                setHideWithAttr(formDataGetDTO, explainMap, data, newData);
                break;
            case TRANSFER:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(TransferEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, TransferEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.TRANSFER.getCode(), explainMap);
                setWarehouseManager(corpid,data,newData,TransferEnum.INTO_WAREHOUSE_ID.getAttr(),TransferEnum.OUT_WAREHOUSE_ID.getAttr());
                break;
            case ASSEMBLE:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(AssembleEnum.OUT_PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                proFormHelp.setProductAccuracy(explainMap.get(AssembleEnum.IN_PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, AssembleEnum.IN_PRODUCTS.getAttr(), XbbRefTypeEnum.ASSEMBLE.getCode(), explainMap);
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, AssembleEnum.OUT_PRODUCTS.getAttr(), XbbRefTypeEnum.ASSEMBLE.getCode(), explainMap);
                setWarehouseManager(corpid,data,newData, AssembleEnum.INTO_WAREHOUSE_ID.getAttr(),AssembleEnum.OUT_WAREHOUSE_ID.getAttr());
                break;
            case BOMBILL:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(BomBillEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                proFormHelp.setProductAccuracy(explainMap.get(BomBillEnum.MATERIEL.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, BomBillEnum.PRODUCT.getAttr(), XbbRefTypeEnum.BOM_BILL.getCode(), explainMap);
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, BomBillEnum.MATERIEL.getAttr(), XbbRefTypeEnum.BOM_BILL.getCode(), explainMap);
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("bomId", entityId);
                param.put("corpid", corpid);
                param.put("del",0);
                param.put("isMain",1);
                List<UserTeamEntity> userTeamEntityList = bomUserModel.findBaseEntitys(param);
                StringBuilder managerNameBuilder = new StringBuilder();
                setManagers(userTeamEntityList, managerNameBuilder);
                newData.put(AdditionalPrintAttrEnum.MANAGER.getAttr(),managerNameBuilder.toString());

                break;
            case PRODUCTIONORDER:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ProductionOrderEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                proFormHelp.setProductAccuracy(explainMap.get(ProductionOrderEnum.MATERIEL.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, ProductionOrderEnum.PRODUCT.getAttr(), XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), explainMap);
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, ProductionOrderEnum.MATERIEL.getAttr(), XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), explainMap);
                Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put("productionOrderId", entityId);
                map.put("corpid", corpid);
                map.put("del",0);
                map.put("isMain",1);
                List<UserTeamEntity> productionOrderUserList = productionOrderUserModel.findBaseEntitys(map);
                StringBuilder managerBuilder = new StringBuilder();
                setManagers(productionOrderUserList, managerBuilder);
                newData.put(AdditionalPrintAttrEnum.MANAGER.getAttr(),managerBuilder.toString());
                break;
            case PAYMENT_SHEET:
                printFundType = formDataGetVO.getFormList().getData().getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
                newData.put("printFundType", printFundType);
                if(CollectionsUtil.isNotEmpty(amountDetail)) {
                    if (amountDetail.size() > BasicConstant.ONE) {
                        disposePaymentSheetAmount(newData, amountDetail);
                    }
                }
                /*
                 * Pro模式预收款核销类型回款单，无支付方式
                 * 但是经销商类型回款单，预收款核销类型回款单的支付方式后端置为：预收款账户，即此时有值。所以要做特殊处理
                 */
                String payMethod = newData.getString(PaymentSheetBaseEnum.PAY_METHOD.getAttr());
                if (Objects.equals(printFundType, SheetTypeEnum.WRITE_OFF_PREPAYMENT.getCode()) && StringUtil.isNotEmpty(payMethod)) {
                    String payMethodStr = PayMethodDistributorEnum.getNameByCode(payMethod);
                    newData.put(PaymentSheetBaseEnum.PAY_METHOD.getAttr(), payMethodStr);
                }
                break;
            case INVOICE:
                // 处理发票中的寄送信息的地址
                addInvoiceLinkAddress(newData, XbbRefTypeEnum.INVOICE);
                if(CollectionsUtil.isNotEmpty(amountDetail)) {
                    disposeInvoiceTotalMoney(newData, amountDetail);
                }
                break;
            case PAY_SHEET:
                printFundType = formDataGetVO.getFormList().getData().getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
                newData.put("printFundType", printFundType);
                if(CollectionsUtil.isNotEmpty(amountDetail)) {
                    if (amountDetail.size() > BasicConstant.ONE) {
                        disposePaySheetAmount(newData, amountDetail);
                    }
                }
                break;
            case INVOICE_PURCHASE:
                addInvoiceLinkAddress(newData, XbbRefTypeEnum.PURCHASE_INVOICE);
                if(CollectionsUtil.isNotEmpty(amountDetail)) {
                    disposeInvoicePurchaseTotalMoney(newData, amountDetail);
                }
                break;
            case WORKORDER:
                // 客户地址和客户电话
                workOrderPhoneAddress(corpid, data,newData);
                // 联系人
                workOrderContact(corpid,data,newData);
                // 关联产品
                formDataGetDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, WorkOrderEnum.SPARE_PARTS.getAttr(), XbbRefTypeEnum.WORK_ORDER.getCode(), explainMap);
                // 部分字段未启用或不可见的处理
                setHideWithAttr(formDataGetDTO, explainMap, data, newData);
                // 处理工单进展和工单动态
                if (StringUtil.isNotEmpty(workOrderProcess)) {
                    addWorkOrderDynamic(newData,workOrderProcess);
                }
                if (StringUtil.isNotEmpty(workOrderDynamic)) {
                    addWorkOrderDynamic(newData,workOrderDynamic);
                }
                break;
            case CUSTOMER_STATEMENT:
                formDataGetDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_STATEMENT.getCode());
                //处理客户对账单相应问题
                handleCustomerStatement(formDataGetDTO, data, newData);
                break;
            case CUSTOMER_STATEMENT_STATISTIC:
                formDataGetDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_STATEMENT_STATISTIC.getCode());
                //获取对账单的快照数据
                handleStatementSnapshot(formDataGetDTO, data, newData);
                break;
            case COST_ADJUST:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(CostAdjustEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttr(formDataGetDTO,corpid,data,newData, CostAdjustEnum.PRODUCT.getAttr(), XbbRefTypeEnum.COST_ADJUST.getCode(), explainMap);
                break;
            case RECEIPT_ORDER:
            case WORK_ORDER_V2:
                PrintSubFromDataGetDTO printSubFromDataGetDTO = new PrintSubFromDataGetDTO();
                BeanUtil.copyProperties(formDataGetDTO,printSubFromDataGetDTO);
                printSubFromDataGetDTO.setData(data);
                printSubFromDataGetDTO.setNewData(newData);
                printSubFromDataGetDTO.setFormDataGetDTO(formDataGetDTO);
                printSubFromDataGetDTO.setExplainMap(explainMap);
                String subFromDataResult;
                try {
                    subFromDataResult = workOrderPrintClient.getPrintSubFromData(printSubFromDataGetDTO, LocaleContextHolder.getLocale().toString());
                } catch (Exception e) {
                    LOG.error("获取表单数据报错", e);
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nStringConstant.FORM_DATA_ERROR);
                }
                JSONObject subFromDataJson = JsonHelperUtil.parseObject(subFromDataResult);
                if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)subFromDataJson.get(StringConstant.CODE)) {
                    throw new XbbException(subFromDataJson.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
                }
                PrintGetDataVO getDataVO = JsonHelperUtil.parseObject(subFromDataJson.getString("result"),PrintGetDataVO.class);
                newData = getDataVO.getData();
                break;
            default:
                break;
        }
        printGetDataVO.setData(newData);
        printGetDataVO.setDataLinkInfo(dataLinkInfo);
        printGetDataVO.setAttrInfo(attrInfo);
        valueArray.add(printGetDataVO);
        return valueArray;
    }

    private void handleStatementSnapshot(FormDataGetDTO formDataGetDTO, JSONObject data, JSONObject newData) throws XbbException{
        newData.putAll(data);
        //处理对账日期字段
        List<Long> checkingDateList  = formDataGetDTO.getCheckingDate();
        if (CollectionsUtil.isEmpty(checkingDateList)) {
            throw new XbbException(StatementErrorCodeEnum.API_ERROR_249004);
        }
        String beginDate = DateUtil.getDateString(checkingDateList.get(0).intValue());
        String endDate = DateUtil.getDateString(checkingDateList.get(1).intValue());
        String fininalDate = beginDate + I18nMessageUtil.getMessage(StringConstant.TO) + endDate;
        newData.put(CustomerStatementEnum.CHECKING_DATE.getAttr(), fininalDate);
        //处理客户名称
        newData.put(CustomerStatementEnum.CUSTOMER_ID.getAttr(), newData.getString(CustomerManagementEnum.NAME.getAttr()));

        //下面是处理表格里面的数据
        StatementSummaryDetailDTO detailDTO = new StatementSummaryDetailDTO();
        BeanUtil.copyProperties(formDataGetDTO, detailDTO);
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        try {
            // 查询列表里面的数据
            detailDTO.setCheckDate(checkingDateList);
            detailDTO.setDataId(formDataGetDTO.getStatementId());
            detailDTO.setFromPrint(BasicConstant.ONE);
            String customerTableStr = formFeignClient.statementDetail(detailDTO, lang);

            JSONObject customerTableResultObj = JsonHelperUtil.parseObject(customerTableStr);
            String resultObjString = customerTableResultObj.getString(StringConstant.RESULT);
            StatementSummaryDetailVO detailVO = JsonHelperUtil.parseObject(resultObjString, StatementSummaryDetailVO.class);
            JSONObject jsonObject = new JSONObject();
            if (Objects.nonNull(detailVO)) {
                List<StatementTableDataExportPojo> printData = detailVO.getPrintData();
                List<JSONObject> statementList = new ArrayList<>();
                // 将字段转化成data中对应的key
                for (StatementTableDataExportPojo pojo : printData) {
                    JSONObject statement = new JSONObject();
                    statement.put(CustomerStatementEnum.CHECKING_DATE.getAttr(), pojo.getCheckingDate());
                    statement.put(CustomerStatementEnum.BUSINESS_TYPE.getAttr(), pojo.getBusinessType());
                    statement.put(CustomerStatementEnum.STATEMENT_ID.getAttr(), pojo.getStatementId());
                    statement.put(CustomerStatementEnum.CONTRACT_ID.getAttr(), pojo.getContractId());
                    statement.put(CustomerStatementEnum.SOURCE_ID.getAttr(), pojo.getSourceId());
                    statement.put(CustomerStatementEnum.AMOUNT_RECEIVABLE.getAttr(), pojo.getAmountReceivable());
                    statement.put(CustomerStatementEnum.AMOUNT_RECEIVED.getAttr(), pojo.getAmountReceived());
                    statement.put(CustomerStatementEnum.WRITE_OFF_AMOUNT.getAttr(), pojo.getWriteOffAmount());
                    statement.put(CustomerStatementEnum.BALANCE_RECEIVABLE.getAttr(), pojo.getBalanceReceivable());
                    //生成对账单打印时添加回款类型一列，针对应收款
                    statement.put(CustomerStatementEnum.PAYMENT_TYPE.getAttr(), pojo.getPaymentType());
                    JSONArray products = pojo.getArray_1();
                    if (CollectionsUtil.isNotEmpty(products)) {
                        JSONObject fisrtProduct = products.getJSONObject(0);
                        fisrtProduct.put(SelectProductEnum.SPECIFICATION.getAttr(), getSpec(fisrtProduct.getString(SelectProductEnum.SPECIFICATION.getAttr())));
                        statement.put(CustomerStatementEnum.PRODUCT.getAttr(), fisrtProduct);
                        statementList.add(statement);
                        int size = products.size();
                        if (size > 1) {
                            for (int i = 1; i < size; i++) {
                                JSONObject product = products.getJSONObject(i);
                                product.put(SelectProductEnum.SPECIFICATION.getAttr(), getSpec(product.getString(SelectProductEnum.SPECIFICATION.getAttr())));
                                JSONObject statementWithProduct = new JSONObject();
                                statementWithProduct.put(CustomerStatementEnum.PRODUCT.getAttr(), product);
                                statementList.add(statementWithProduct);
                            }
                        }
                    } else {
                        statementList.add(statement);
                    }
                }
                jsonObject.put(PrintConstant.ATTRLIST, statementList);
                if (CollectionsUtil.isNotEmpty(printData)) {
                    //导出时，最后一行是汇总信息
                    StatementTableDataExportPojo lastRow = printData.get(printData.size() - 1);
                    String balanceReceivable = lastRow.getBalanceReceivable();
                    String balanceReceivableChinese = lastRow.getBalanceReceivableChinese();
                    balanceReceivable += String.format(SymbolConstant.BRACKETS_ENGLISH, balanceReceivableChinese);
                    JSONObject sum = new JSONObject();
                    sum.put(CustomerStatementEnum.BALANCE_RECEIVABLE.getAttr(), balanceReceivable);
                    jsonObject.put(PrintConstant.SUMATTRLIST, sum);
                }
            }
            newData.put(PrintSpecialAttrEnum.CUSTOMER_STATEMENT_DETAIL.getAttr(), jsonObject);

        }catch (Exception e) {
            LOG.error("获取客户对账单数据报错:{}",e.getMessage());
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void dealTemplateField(JSONObject newData, List<FieldAttrEntity> fieldAttrEntities) {
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.TEMPLATE_FIELD.getType())){
                JSONObject jsonObject = newData.getJSONObject(fieldAttrEntity.getAttr());
                if (jsonObject==null) {
                    return;
                }
                newData.put(fieldAttrEntity.getAttr(), jsonObject.get(OnlineEditorConstant.BASE_CONTRACT_NAME));
            }
        }
    }

    private void filterLabelData(JSONObject newData, List<FieldAttrEntity> fieldAttrEntities) {
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LABEL.getType())){
                JSONArray jsonArray = newData.getJSONArray(fieldAttrEntity.getAttr());
                if (CollectionsUtil.isEmpty(jsonArray)) {
                    return;
                }
                StringBuilder label = new StringBuilder();
                for (Object obj : jsonArray) {
                    String name = "";
                    if (obj instanceof JSONObject && ((JSONObject) obj).containsKey("name")) {
                        name = ((JSONObject) obj).getString("name");
                    }
                    if (StringUtil.isEmpty(name)) {
                        continue;
                    }
                    if (label.length() != BasicConstant.ZERO) {
                        label.append(StringConstant.CHINESE_COMMA);
                    }
                    label.append(name);
                }
                newData.put(fieldAttrEntity.getAttr(), label);
            }
        }
    }

    /**
     * 处理客户对账单
     *
     * @param formDataGetDTO 查询的参数
     * @param data 客户数据
     * @param newData 新的客户数据
     */
    private void handleCustomerStatement(FormDataGetDTO formDataGetDTO, JSONObject data, JSONObject newData) throws XbbException {
        newData.putAll(data);
        //处理对账日期字段
        List<Long> checkingDateList  = formDataGetDTO.getCheckingDate();
        if (CollectionsUtil.isEmpty(checkingDateList)) {
            throw new XbbException(StatementErrorCodeEnum.API_ERROR_249004);
        }
        String beginDate = DateUtil.getDateString(checkingDateList.get(0).intValue());
        String endDate = DateUtil.getDateString(checkingDateList.get(1).intValue());
        String fininalDate = beginDate + I18nMessageUtil.getMessage(StringConstant.TO) + endDate;
        newData.put(CustomerStatementEnum.CHECKING_DATE.getAttr(), fininalDate);
        //处理客户名称
        newData.put(CustomerStatementEnum.CUSTOMER_ID.getAttr(), newData.getString(CustomerManagementEnum.NAME.getAttr()));

        //下面是处理表格里面的数据
        StatementCustomerTableDTO statementCustomerTableDTO = new StatementCustomerTableDTO();
        statementCustomerTableDTO.setFromExport(BasicConstant.ONE);
        BeanUtil.copyProperties(formDataGetDTO, statementCustomerTableDTO);
        StatementCustomerSummaryDTO statementCustomerSummaryDTO = new StatementCustomerSummaryDTO();
        BeanUtil.copyProperties(formDataGetDTO, statementCustomerSummaryDTO);
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        try {
            // 查询列表里面的数据
            statementCustomerTableDTO.setCustomerId(formDataGetDTO.getDataId());
            String customerTableStr = formFeignClient.getCustomerTableData(statementCustomerTableDTO, lang);
            JSONObject customerTableResultObj = JsonHelperUtil.parseObject(customerTableStr);
            String resultObjString = customerTableResultObj.getString(StringConstant.RESULT);
            StatementCustomerTableVO statementCustomerTableVO = JsonHelperUtil.parseObject(resultObjString, StatementCustomerTableVO.class);
            JSONObject jsonObject = new JSONObject();
            if (Objects.nonNull(statementCustomerTableVO)) {
                List<StatementTableDataExportPojo> exportData = statementCustomerTableVO.getExportData();
                List<JSONObject> statementList = new ArrayList<>();
                // 将字段转化成data中对应的key
                for (StatementTableDataExportPojo pojo : exportData) {
                    JSONObject statement = new JSONObject();
                    statement.put(CustomerStatementEnum.CHECKING_DATE.getAttr(), pojo.getCheckingDate());
                    statement.put(CustomerStatementEnum.BUSINESS_TYPE.getAttr(), pojo.getBusinessType());
                    statement.put(CustomerStatementEnum.STATEMENT_ID.getAttr(), pojo.getStatementId());
                    statement.put(CustomerStatementEnum.CONTRACT_ID.getAttr(), pojo.getContractId());
                    statement.put(CustomerStatementEnum.SOURCE_ID.getAttr(), pojo.getSourceId());
                    statement.put(CustomerStatementEnum.AMOUNT_RECEIVABLE.getAttr(), pojo.getAmountReceivable());
                    statement.put(CustomerStatementEnum.AMOUNT_RECEIVED.getAttr(), pojo.getAmountReceived());
                    statement.put(CustomerStatementEnum.WRITE_OFF_AMOUNT.getAttr(), pojo.getWriteOffAmount());
                    statement.put(CustomerStatementEnum.BALANCE_RECEIVABLE.getAttr(), pojo.getBalanceReceivable());
                    //生成对账单打印时添加回款类型一列，针对应收款
                    statement.put(CustomerStatementEnum.PAYMENT_TYPE.getAttr(), pojo.getPaymentType());
                    JSONArray products = pojo.getArray_1();
                    if (CollectionsUtil.isNotEmpty(products)) {
                        JSONObject fisrtProduct = products.getJSONObject(0);
                        fisrtProduct.put(SelectProductEnum.SPECIFICATION.getAttr(), getSpec(fisrtProduct.getString(SelectProductEnum.SPECIFICATION.getAttr())));
                        statement.put(CustomerStatementEnum.PRODUCT.getAttr(), fisrtProduct);
                        statementList.add(statement);
                        int size = products.size();
                        if (size > 1) {
                            for (int i = 1; i < size; i++) {
                                JSONObject product = products.getJSONObject(i);
                                product.put(SelectProductEnum.SPECIFICATION.getAttr(), getSpec(product.getString(SelectProductEnum.SPECIFICATION.getAttr())));
                                JSONObject statementWithProduct = new JSONObject();
                                statementWithProduct.put(CustomerStatementEnum.PRODUCT.getAttr(), product);
                                statementList.add(statementWithProduct);
                            }
                        }
                    } else {
                        statementList.add(statement);
                    }
                }
                jsonObject.put(PrintConstant.ATTRLIST, statementList);
                if (CollectionsUtil.isNotEmpty(exportData)) {
                    //导出时，最后一行是汇总信息
                    StatementTableDataExportPojo lastRow = exportData.get(exportData.size() - 1);
                    String balanceReceivable = lastRow.getBalanceReceivable();
                    String balanceReceivableChinese = lastRow.getBalanceReceivableChinese();
                    balanceReceivable += String.format(SymbolConstant.BRACKETS_ENGLISH, balanceReceivableChinese);
                    JSONObject sum = new JSONObject();
                    sum.put(CustomerStatementEnum.BALANCE_RECEIVABLE.getAttr(), balanceReceivable);
                    jsonObject.put(PrintConstant.SUMATTRLIST, sum);
                }
            }
            newData.put(PrintSpecialAttrEnum.CUSTOMER_STATEMENT_DETAIL.getAttr(), jsonObject);

        }catch (Exception e) {
            LOG.error("获取客户对账单数据报错:{}",e.getMessage());
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    public String getSpec(String spec){
        StringBuilder stringBuilder = new StringBuilder();
        JSONObject specifition;
        try {
            specifition = JSONObject.parseObject(spec);
        } catch (Exception e) {
            return spec;
        }
        if (Objects.nonNull(specifition)){
            specifition.forEach((key,value)->  StringUtil.stringBuilderAppendSuffix(stringBuilder,"/",value));
        }
        return stringBuilder.toString();
    }

    /**
     * 工单联系客户
     * @param corpid
     * @param data
     * @param newData
     */
    private void workOrderContact(String corpid, JSONObject data, JSONObject newData) {
        JSONArray linkContactArray = JsonHelperUtil.parseArray(data.getString(WorkOrderEnum.LINK_CONTACT.getAttr()));
        if (linkContactArray.isEmpty()) {
            return;
        }
        // 关联联系人
        JSONObject linkContact =  (JSONObject) linkContactArray.get(0);
        Long contactId = StringUtil.StringToLong(linkContact.getString("id"));
        ContactEntityExt contactEntityExt = contactModel.getByKey(contactId,corpid);
        if (contactEntityExt == null) {
            return;
        }
        JSONObject dataObj = contactEntityExt.getData();
        if (dataObj == null){
            return;
        }
        // 联系人电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(ContactEnum.PHONE.getAttr()));
        if (phoneArray.isEmpty()) {
            // 无电话，直接返回
            return;
        }
        JSONObject phoneObj = phoneArray.getJSONObject(0);
        newData.put(AdditionalPrintAttrEnum.CONTACT_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
    }

    /**
     * 工单客户与电话
     * @param corpid
     * @param data
     * @param newData
     */
    private void workOrderPhoneAddress(String corpid, JSONObject data, JSONObject newData) {
        JSONArray linkCustomerArray = JsonHelperUtil.parseArray(data.getString(WorkOrderEnum.LINK_CUSTOMER.getAttr()));
        if (linkCustomerArray.isEmpty()) {
            return;
        }
        // 关联客户
        JSONObject linkCustomer =  (JSONObject) linkCustomerArray.get(0);
        Long customerId = StringUtil.StringToLong(linkCustomer.getString("id"));
        CustomerEntityExt customerEntity = customerModel.getByKey(customerId,corpid);
        if (customerEntity == null) {
            return;
        }
        JSONObject dataObj = customerEntity.getData();
        if (dataObj == null){
            return;
        }
        // 客户地址
        JSONObject addressObj = JsonHelperUtil.parseObject(dataObj.getString(CustomerManagementEnum.ADDRESS.getAttr()));
        String formatAddress = getFormatAddress(addressObj);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_ADDRESS.getAttr(),formatAddress);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_ADDRESS.getAttr() + "_full",addressObj);
        // 客户电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(CustomerManagementEnum.PHONE.getAttr()));
        if (phoneArray.isEmpty()) {
            // 无电话，直接返回
            return;
        }
        JSONObject phoneObj = phoneArray.getJSONObject(0);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
        // newData.put(WorkOrderEnum.LINK_CUSTOMER.getAttr(),linkCustomer.getString("name"));
    }


    /**
     * 处理工单动态
     * @param newData
     */
    private void addWorkOrderDynamic(JSONObject newData,String workOrderDynamic) throws XbbException{
        JSONObject resultObj = JsonHelperUtil.parseObject(workOrderDynamic);
        if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
            throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
        }
        JSONObject jsonObject = JsonHelperUtil.parseObject(resultObj.getString("result"), JSONObject.class);
        newData.putAll(jsonObject);
    }
    /**
     * 打印中部分字段不可见时隐藏
     * @param formDataGetDTO
     * @param explainMap
     * @param data
     * @param newData
     * @return void
     * @author 石安
     * @date 2019-09-09
     * @modify 2019/10/25 by xingxing.xiao 加上 "创建人和协同人、负责人" 及 "子表单校验"
     */
    private void setHideWithAttr(FormDataGetDTO formDataGetDTO, Map<String, FieldAttrEntity> explainMap, JSONObject data, JSONObject newData) {
        try {
            PrintDataVisibleDTO printDataVisibleDTO = new PrintDataVisibleDTO();
            BeanUtil.copyProperties(formDataGetDTO, printDataVisibleDTO, false);
            printDataVisibleDTO.setFormDataGetDTO(formDataGetDTO);
            printDataVisibleDTO.setExplainMap(explainMap);
            //  获取创建人和协同人、负责人(判断高级规则用)
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            String dataResult = formFeignClient.getOwnerIdAndCoUserIdToPrint(printDataVisibleDTO, lang);
            JSONObject resultObj = JsonHelperUtil.parseObject(dataResult);
            if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
                LOG.error("接口请求返回 dataResult:", dataResult);
                throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
            }
            HandlerExplainDTO handlerExplainDTO = JsonHelperUtil.parseObject(resultObj.getString("result"), HandlerExplainDTO.class);

            for (String attr : data.keySet()) {
                if (explainMap.containsKey(attr) && Objects.nonNull(explainMap.get(attr))) {
                    FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                    if (!ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                        if (Objects.equals(fieldAttrEntity.getIsOpen(), 0) || Objects.equals(fieldAttrEntity.getIsOpen(), 2)) {
                            newData.put(attr, "");
                        } else if (ExplainUtil.isFieldNeedHide(fieldAttrEntity, handlerExplainDTO)) {
                            newData.put(attr, StringConstant.INVISIBLE_VALUE);
                        }
                    } else if (ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                        // 子表单相关数据
                        Map<String, FieldAttrEntity> subFieldMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainMap.get(attr).getSubForm().getItems()), null);
                        // attrList 取自 adjustAttrValue()方法
                        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());
                        // 工作报告今日计划不走权限
                        if (Objects.equals(PrintTemplateTypeEnum.WORKREPORT.getCode(), formDataGetDTO.getBusinessType()) && (fieldTypeEnum != null  && fieldTypeEnum.equals(FieldTypeEnum.SWITCH_TEXT))) {
                            continue;
                        }
                        // 联系方式(工单特殊处理)(其他的我也不知道存在这样的情况)
                        if (Objects.equals(WorkOrderEnum.CONTACT_INFORMATION.getAttr(),attr) && Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(),formDataGetDTO.getBusinessType())){
                            FieldAttrEntity fieldAttr = explainMap.get(attr);
                            if(Objects.nonNull(fieldAttr) && ExplainUtil.isFieldNeedHide(fieldAttr, handlerExplainDTO)) {
                                newData.put(attr, StringConstant.INVISIBLE_VALUE);
                            }
                            continue;
                        }
                        JSONArray jsonArray;
                        try {
                            JSONObject attrObj = FastJsonHelper.getJsonObjectFromFormData(newData, attr);
                            jsonArray = FastJsonHelper.getJsonArrFromFormData(attrObj, PrintConstant.ATTRLIST);
                        } catch (XbbException e) {
                            jsonArray = null;
                        }
                        if (Objects.isNull(jsonArray)) {
                            continue;
                        }
                        for (Object obj : jsonArray) {
                            JSONObject jsonObject = (JSONObject) obj;
                            if (Objects.isNull(jsonObject)) {
                                continue;
                            }
                            for(String subAttr: jsonObject.keySet()) {
                                FieldAttrEntity subField = subFieldMap.get(subAttr);
                                if (Objects.nonNull(subField) && Objects.equals(subField.getIsOpen(), 2)) {
                                    jsonObject.put(subAttr, "");
                                    continue;
                                }
                                if(Objects.nonNull(subField) && ExplainUtil.isFieldNeedHide(subField, handlerExplainDTO)) {
                                    jsonObject.put(subAttr, StringConstant.INVISIBLE_VALUE);
                                }
                            }
                        }
                    }
                }
            }
        } catch (XbbException e) {
            LOG.warn("setHideWithAttr 隐藏打印中部分字段不可见出错", e);
        }
    }


    /**
     * 调整字段数据值（有些数组要转成String）
     * @param headFieldAttrList 详情接口回参
     * @param newData 新返回数据
     * @param fieldAttrEntities 表单字段解释
     * @param dataLinkInfo 关联数据信息
     */
    private void adjustAttrValue(List<FieldAttrEntity> headFieldAttrList, JSONObject newData, List<FieldAttrEntity> fieldAttrEntities ,JSONObject dataLinkInfo, UserVO loginUser) {
        // 因为详情展示的全一些（就是没有子表单），所以用详情返回的解释
        for (FieldAttrEntity fieldAttrEntity : headFieldAttrList) {
            String attr = fieldAttrEntity.getAttr();
            Integer fieldType = fieldAttrEntity.getFieldType();
            String dateType = fieldAttrEntity.getDateType();
            String saasAttr = fieldAttrEntity.getSaasAttr();
            LinkInfoPojo linkInfoPojo = fieldAttrEntity.getLinkInfo();
            if (WorkReportDailyEnum.REVIEWER.getSaasAttr().equals(saasAttr)) {
                // 工作报告已读人列表跳过
                continue;
            }
            adjustAttrValueByFieldType(newData, attr, dateType, fieldType);
            dataLinkInfo.put(attr,linkInfoPojo);
        }
        // 22497 生产领料单设计页生产领料编号、领料日期、关联生产单字段设置高级不可见，打印时展示--
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            // 是否允许可见,是否开启高级可见设置
            if (Objects.equals(fieldAttrEntity.getVisible(), BasicConstant.ONE) && Objects.equals(fieldAttrEntity.getVisibleScopeEnable(), BasicConstant.ONE)) {
                VisibleRulePoJo visibleScopeRule = fieldAttrEntity.getVisibleScopeRule();
                if (Objects.nonNull(visibleScopeRule)) {
                    if (!Objects.equals(visibleScopeRule.getType(), VisibleTypeEnum.NOT_SHOW_ANYONE.getType())) {
                        // 非高级不见设置跳过
                        continue;
                    }
                    List<VisibleRuleVO> userList = visibleScopeRule.getUserList();
                    List<String> userIds = new ArrayList<>();
                    userList.forEach(visibleRuleVO -> {
                        userIds.add(visibleRuleVO.getUserId());
                    });
                    if (userIds.size() > 0 && userIds.contains(loginUser.getUserId())) {
                        newData.put(fieldAttrEntity.getAttr(),"--");
                    }
                }
            } else if (BasicConstant.ZERO.equals(fieldAttrEntity.getIsOpen())) {
                newData.remove(fieldAttrEntity.getAttr());
            }
        }
        // 处理子表单字段
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            String attr = fieldAttrEntity.getAttr();
            Integer fieldType = fieldAttrEntity.getFieldType();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum == null || !fieldTypeEnum.equals(FieldTypeEnum.SUB_FORM)) {
                // 不是子表单的跳过
                continue;
            }
            SubFormPoJo subFormPoJo = fieldAttrEntity.getSubForm();
            List<? extends FieldAttrEntity> items = subFormPoJo.getItems();
            if (items == null || items.isEmpty()) {
                // 子表单无字段跳过
                continue;
            }
            // 子表单数据列表 格式化
            JSONArray valueArray = JsonHelperUtil.parseArray(newData.getString(attr));
            // 子表单字段的关联数据
            JSONObject dataLinkInfoSub = new JSONObject();
            for (Object obj : valueArray) {
                JSONObject valueObj = (JSONObject)obj;
                for (FieldAttrEntity item : items) {
                    String thisAttr = item.getAttr();
                    Integer thisFieldType = item.getFieldType();
                    String dateType = item.getDateType();
                    adjustAttrValueByFieldType(valueObj, thisAttr, dateType, thisFieldType);
                    dataLinkInfoSub.putIfAbsent(thisAttr,item.getLinkInfo());
                }
            }
            // 将格式化后的数据放回
            JSONObject result = new JSONObject();
            result.put(PrintConstant.ATTRLIST,valueArray);
            result.put("dataLinkInfo",dataLinkInfoSub);
            newData.put(attr,result);
        }
    }

    /**
     * 过虑关联数据未选择的值
     *
     * @param newData 数据
     * @param fieldAttrEntities 解释列表
     */
    private void filterLinkDataForNoChoose(JSONObject newData, List<FieldAttrEntity> fieldAttrEntities) {
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            String attr = fieldAttrEntity.getAttr();
            Integer fieldType = fieldAttrEntity.getFieldType();
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            if (fieldTypeEnum == null || !fieldTypeEnum.equals(FieldTypeEnum.LINK_DATA)) {
                // 不是关联数据的跳过
                continue;
            }

            boolean removeFlag = false;
            Object linkDataValue = newData.get(attr);
            if (Objects.isNull(linkDataValue)) {
                removeFlag = true;
            } else if (linkDataValue instanceof Integer && Objects.equals(linkDataValue, BasicConstant.ZERO)) {
                removeFlag = true;
            }
            if (removeFlag) {
                newData.remove(attr);
            }
        }
    }

    /**
     * 根据字段类型，调整字段返回值
     * @param newData 最终返回
     * @param attr 字段
     * @param dateType 日期类型
     * @param fieldType 字段类型
     */
    private void adjustAttrValueByFieldType(JSONObject newData, String attr, String dateType, Integer fieldType) {
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (fieldTypeEnum == null) {
            return;
        }
        Object value = newData.get(attr);
        switch (fieldTypeEnum) {
            case LINK_BUSINESS_SINGLE:
            case LINK_RECEIVER:
                // 关联业务数据 [{"id":"XX","name":"XXX"}]
                JSONArray array = JsonHelperUtil.parseArray(newData.getString(attr));
                if (array.isEmpty()) {
                    break;
                }
                JSONObject bObj = array.getJSONObject(0);
                String name = bObj.get(StringConstant.SAAS_LINK_BUSINESS_NAME) == null ? "" : (String)bObj.get(StringConstant.SAAS_LINK_BUSINESS_NAME);
                newData.put(attr,name);
                break;
            case LINK_BUSINESS_MULTI:
                // 关联业务多选
                JSONArray arrays = JsonHelperUtil.parseArray(newData.getString(attr));
                String resultStr = setJsonArrayStr(arrays,StringConstant.SAAS_LINK_BUSINESS_NAME);
                newData.put(attr,resultStr);
                break;
            case USER:
            case CREATORID:
            case DEPT:
            case DEPARTMENTID:
                // 成员单选或部门单选 {"id":1,"name":"XXX","avatar":""}
                JSONObject userObj = JsonHelperUtil.parseObject(newData.getString(attr));
                String useName = userObj.getString(StringConstant.SAAS_LINK_BUSINESS_NAME) == null ? "" : userObj.getString(StringConstant.SAAS_LINK_BUSINESS_NAME);
                newData.put(attr,useName);
                break;
            case USER_GROUP:
            case DEPT_GROUP:
            case OWNERID:
            case COUSERID:
                // 成员或部门多选 [{}]
                JSONArray userArray = JsonHelperUtil.parseArray(newData.getString(attr));
                newData.put(attr, setJsonArrayStr(userArray,StringConstant.SAAS_LINK_BUSINESS_NAME));
                break;
            case DATETIME:
            case ADDTIME:
            case UPDATETIME:
            case ENDTIME:
            case CLOSETIME:
                String dataTime = "";
                if (value instanceof String) {
                    Long dateLong = StringUtil.StringToLong((String)value);
                    dataTime = DateTimeUtil.getStringEpochSecond(dateLong,dateType);
                } else if (value instanceof Integer) {
                    Integer dateInt = (Integer)value;
                    dataTime = DateTimeUtil.getString(dateInt,dateType);
                } else if (value instanceof Long) {
                    Long dateLongSen = (Long)value;
                    dataTime = DateTimeUtil.getStringEpochSecond(dateLongSen,dateType);
                }
                dataTime = Objects.isNull(dataTime) ? "" : dataTime;
                newData.put(attr,dataTime);
                break;
            case ADDRESS:
            case LOCATION:
                // 地址
                JSONObject addressObj = JsonHelperUtil.parseObject(newData.getString(attr));
                String formatAddress = getFormatAddress(addressObj);
                newData.put(attr,formatAddress);
                newData.put(attr + "_full",addressObj);
                break;
            case CONTACT_NUMBER:
                JSONArray phoneArr = JsonHelperUtil.parseArray(newData.getString(attr));

                if (Objects.nonNull(phoneArr) && !phoneArr.isEmpty()) {
                    StringBuilder phoneStr = new StringBuilder();
                    for (int i = 0; i< phoneArr.size(); i++) {
                        JSONObject phoneObj = phoneArr.getJSONObject(i);
                        String phone = phoneObj.getString(StringConstant.PHONE_TEL_ATTR);
                        phone = Objects.isNull(phone) ? "" : phone;
                        if (phoneStr.length() != BasicConstant.ZERO) {
                            phoneStr.append(";");
                        }
                        phoneStr.append(phone);
                    }
                    newData.put(attr, phoneStr.toString());
                } else {
                    newData.put(attr,"");
                }
                break;
            case SUB_FORM:
                // 子表单，在外层处理
                break;
            case CHECKBOX_GROUP:
            case COMBO_CHECK:
                // 复选框组、下拉框复选
                Object comboObj = newData.get(attr);
                String comboStr;
                if (Objects.isNull(comboObj)) {
                    comboStr = "";
                } else if (comboObj instanceof JSONArray || comboObj instanceof List) {
                    JSONArray comboArray = JsonHelperUtil.parseArray(newData.getString(attr));
                    comboStr = setStringArrayStr(comboArray);
                } else if (comboObj instanceof String) {
                    comboStr = (String) comboObj;
                } else {
                    comboStr = comboObj.toString();
                }
                newData.put(attr,comboStr);
                break;
            case TEXT_CHECK:
                // 文本和勾选 如：BOM版本
                JSONObject checkObj = JsonHelperUtil.parseObject(newData.getString(attr));
                String checkValue = checkObj.getString(StringConstant.VALUE) == null ? "" : checkObj.getString(StringConstant.VALUE);
                newData.put(attr,checkValue);
                break;
            case SWITCH_TEXT:
                // 开关和文本， 如：今日计划
                JSONArray textArray = JsonHelperUtil.parseArray(newData.getString(attr));
                newData.put(attr,setJsonArrayStr(textArray, WorkReportPlanEnum.CONTENT.getAttr()));
                break;
            case COMBO:
            case RADIO_GROUP:
                // 下拉框
                if (value instanceof Map) {
                    Map<String, Object> map = (Map<String, Object>) value;
                    value = map.getOrDefault("text", "");
                }
                value = Objects.isNull(value) ? "" : value;
                newData.put(attr, value);
                break;
                //阶段推进器
            case STAGE_THRUSTER:
                if (value instanceof  Map) {
                    JSONObject stageObject = newData.getJSONObject(attr);
                    if (Objects.nonNull(stageObject)) {
                        newData.put(attr, Objects.isNull(stageObject.getString("text")) ? "" : stageObject.getString("text") );
                    }else {
                        newData.put(attr, "");
                    }
                } else {
                    value = Objects.isNull(value) ? "" : value;
                    newData.put(attr, value);
                }
                break;
            default:
                break;
        }
    }


    /**
     * 合同添加客户地址，客户电话 字段数据
     * @param corpid 公司id
     * @param newData 新data
     */
    private void addCustomerAddressPhone(String corpid,JSONObject data, JSONObject newData) {
        JSONArray linkCustomerArray = JsonHelperUtil.parseArray(data.getString(ContractEnum.LINK_CUSTOMER.getAttr()));
        if (linkCustomerArray.isEmpty()) {
            return;
        }
        // 关联客户
        JSONObject linkCustomer =  (JSONObject) linkCustomerArray.get(0);
        Long customerId = StringUtil.StringToLong(linkCustomer.getString("id"));
        CustomerEntityExt customerEntity = customerModel.getByKey(customerId,corpid);
        if (customerEntity == null) {
            return;
        }
        JSONObject dataObj = customerEntity.getData();
        if (dataObj == null){
            return;
        }
        // 客户地址
        JSONObject addressObj = JsonHelperUtil.parseObject(dataObj.getString(CustomerManagementEnum.ADDRESS.getAttr()));
        String formatAddress = getFormatAddress(addressObj);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_ADDRESS.getAttr(),formatAddress);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_ADDRESS.getAttr() + "_full",addressObj);
        // 客户电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(CustomerManagementEnum.PHONE.getAttr()));
        if (phoneArray.isEmpty()) {
            // 无电话，直接返回
            return;
        }
        JSONObject phoneObj = phoneArray.getJSONObject(0);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
    }

    /**
     * 报价单添加客户地址，客户电话 字段数据
     * @param corpid 公司id
     * @param newData 新data
     */
    private void customerPhoneAddress(String corpid,JSONObject data, JSONObject newData) {
        JSONArray linkCustomerArray = JsonHelperUtil.parseArray(data.getString(QuotationEnum.CUSTOMER_ID.getAttr()));
        if (linkCustomerArray.isEmpty()) {
            return;
        }
        // 关联客户
        JSONObject linkCustomer =  (JSONObject) linkCustomerArray.get(0);
        Long customerId = StringUtil.StringToLong(linkCustomer.getString("id"));
        CustomerEntityExt customerEntity = customerModel.getByKey(customerId,corpid);
        if (customerEntity == null) {
            return;
        }
        JSONObject dataObj = customerEntity.getData();
        if (dataObj == null){
            return;
        }
        // 客户地址
        JSONObject addressObj = JsonHelperUtil.parseObject(dataObj.getString(CustomerManagementEnum.ADDRESS.getAttr()));
        String formatAddress = getFormatAddress(addressObj);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_ADDRESS.getAttr(),formatAddress);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_ADDRESS.getAttr() + "_full",addressObj);
        // 客户电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(CustomerManagementEnum.PHONE.getAttr()));
        if (phoneArray.isEmpty()) {
            // 无电话，直接返回
            return;
        }
        JSONObject phoneObj = phoneArray.getJSONObject(0);
        newData.put(AdditionalPrintAttrEnum.CUSTOMER_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
    }

    /**
     * 报价单添加客户地址，客户电话 字段数据
     * @param corpid 公司id
     * @param newData 新data
     */
    private void contactPhoneAddress(String corpid,JSONObject data, JSONObject newData) {
        JSONArray linkContactArray = JsonHelperUtil.parseArray(data.getString(QuotationEnum.CONTACT_ID.getAttr()));
        if (linkContactArray.isEmpty()) {
            return;
        }
        // 关联联系人
        JSONObject linkContact =  (JSONObject) linkContactArray.get(0);
        Long contactId = StringUtil.StringToLong(linkContact.getString("id"));
        ContactEntityExt contactEntity = contactModel.getByKey(contactId,corpid);
        if (contactEntity == null) {
            return;
        }
        JSONObject dataObj = contactEntity.getData();
        if (dataObj == null){
            return;
        }
        // 联系人地址
        JSONObject addressObj = JsonHelperUtil.parseObject(dataObj.getString(ContactEnum.ADDRESS.getAttr()));
        String formatAddress = getFormatAddress(addressObj);
        newData.put(AdditionalPrintAttrEnum.CONTACT_ADDRESS.getAttr(),formatAddress);
        newData.put(AdditionalPrintAttrEnum.CONTACT_ADDRESS.getAttr() + "_full",addressObj);
        // 联系人电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(ContactEnum.PHONE.getAttr()));
        if (phoneArray.isEmpty()) {
            // 无电话，直接返回
            return;
        }
        JSONObject phoneObj = phoneArray.getJSONObject(0);
        newData.put(AdditionalPrintAttrEnum.CONTACT_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
    }

    /**
     * 添加联系人电话 字段数据
     * @param corpid 公司id
     * @param newData 新data
     */
    private void addContactPhone(String corpid,JSONObject data, JSONObject newData) {
        JSONArray linkContactArray = JsonHelperUtil.parseArray(data.getString(ContractEnum.LINK_CONTACT.getAttr()));
        if (linkContactArray.isEmpty()) {
            return;
        }
        // 关联联系人
        JSONObject linkContact =  (JSONObject) linkContactArray.get(0);
        Long contactId = StringUtil.StringToLong(linkContact.getString("id"));
        ContactEntityExt contactEntityExt = contactModel.getByKey(contactId,corpid);
        if (contactEntityExt == null) {
            return;
        }
        JSONObject dataObj = contactEntityExt.getData();
        if (dataObj == null){
            return;
        }
        // 联系人电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(ContactEnum.PHONE.getAttr()));
        if (phoneArray.isEmpty()) {
            // 无电话，直接返回
            return;
        }
        JSONObject phoneObj = phoneArray.getJSONObject(0);
        newData.put(AdditionalPrintAttrEnum.CONTACT_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
    }

    /**
     * 处理销项发票/进项发票中的寄送信息的地址
     * @param newData 数据data
     * @param xbbRefTypeEnum 业务类型
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void addInvoiceLinkAddress(JSONObject newData, XbbRefTypeEnum xbbRefTypeEnum) {
        switch (xbbRefTypeEnum) {
            case INVOICE:
                addInvoiceLinkAddress(newData, InvoiceEnum.CUSTOMER_INVOICE.getAttr(), InvoiceEnum.CUSTOMER_EXPRESS.getAttr());
                break;
            case PURCHASE_INVOICE:
                addInvoiceLinkAddress(newData, PurchaseInvoiceEnum.CUSTOMER_INVOICE.getAttr(), PurchaseInvoiceEnum.CUSTOMER_EXPRESS.getAttr());
                break;
            default:
                break;
        }
    }
    /**
     * 处理发票中的寄送信息的地址
     *
     * @param newData 要返回的数据
     * @param attrInvoice 发票信息字段
     * @param attrExpress 寄送信息字段
     * @author 徐俊杰
     * @date 2020/3/13 10:07
     * @since v1.0
     * @update 2020/4/26 by zcp 兼容进项发票的处理
     */
    private void addInvoiceLinkAddress(JSONObject newData, String attrInvoice, String attrExpress) {
        // 发票抬头类型
        JSONArray invoiceArray = JsonHelperUtil.parseArray(newData.getString(attrInvoice));
        if (Objects.nonNull(invoiceArray) && !invoiceArray.isEmpty()) {
            JSONObject invoiceObj = invoiceArray.getJSONObject(BasicConstant.ZERO);
            // 审批打印为对象，正常打印为value值
            Object titleTypeObj = invoiceObj.get(CustomerInvoiceEnum.TITLE_TYPE.getAttr());
            String titleStr = "";
            if (titleTypeObj instanceof String) {
                titleStr = Objects.equals(titleTypeObj, InvoiceTitleTypeEnum.CORP.getValue()) ?
                                InvoiceTitleTypeEnum.CORP.getName() : InvoiceTitleTypeEnum.PERSON.getName();
            } else if (titleTypeObj instanceof Map) {
                Map<String, Object> map = (Map<String, Object>) titleTypeObj;
                titleStr = map.getOrDefault("text", "").toString();
            }
            invoiceObj.put(CustomerInvoiceEnum.TITLE_TYPE.getAttr(), titleStr);

            newData.put(attrInvoice, invoiceArray);
        }
        JSONArray expressArray = JsonHelperUtil.parseArray(newData.getString(attrExpress));
        if (expressArray == null || Objects.equals(expressArray.size(), 0)) {
            return;
        }
        JSONObject expressJSON = expressArray.getJSONObject(BasicConstant.ZERO);
        JSONObject address = expressJSON.getJSONObject("address_1");
        String formatAddress = getFormatAddress(address);
        expressJSON.put("address_1", formatAddress);
        expressJSON.put("address_1" + "_full", address);
        newData.put(attrExpress, expressArray);
    }

    /**
     * 获取格式化后的地址信息
     * @param addressObj 地址json
     * @return 格式化的地址信息
     */
    private String getFormatAddress(JSONObject addressObj) {
        if (addressObj == null || addressObj.isEmpty()) {
            return "";
        }
        String province = addressObj.getString("province") == null ? "" : addressObj.getString("province");
        String city = addressObj.getString("city") == null ? "" : addressObj.getString("city");
        String district = addressObj.getString("district") == null ? "" : addressObj.getString("district");
        String address = addressObj.getString("address") == null ? "" : addressObj.getString("address");
        return province + city + district + address;
    }

    /**
     * 添加供应商数据
     * @param corpid 公司id
     * @param data 数据
     * @param newData 新数据
     * @param formDataGetDTO 入参
     */
    @SuppressWarnings("unchecked")
    private void addSupplierData(String corpid,JSONObject data, JSONObject newData,String attr,FormDataGetDTO formDataGetDTO){
        JSONArray linkSupplierArray = JsonHelperUtil.parseArray(data.getString(attr));
        Long supplierId ;
        if (!linkSupplierArray.isEmpty()) {
            // 关联供应商
            JSONObject linkSupplier =  (JSONObject) linkSupplierArray.get(0);
            supplierId = StringUtil.StringToLong(linkSupplier.getString("id"));
        } else {
            // 采购退货单存的id
            supplierId = StringUtil.StringToLong(data.getString(attr),0L);
        }
        SupplierEntityExt supplierEntityExt = supplierModel.getByKey(supplierId,corpid);
        if (supplierEntityExt == null) {
            return;
        }
        JSONObject dataObj = supplierEntityExt.getData();
        if (dataObj == null){
            return;
        }
        /*
            供应商联系人名称
            供应商电话
            供应商地址
            供应商负责人
            供应商联系人电话
         */
        // 供应商电话
        JSONArray phoneArray = JsonHelperUtil.parseArray(dataObj.getString(SupplierEnum.PHONE.getAttr()));
        if (!phoneArray.isEmpty()) {
            JSONObject phoneObj = phoneArray.getJSONObject(0);
            newData.put(AdditionalPrintAttrEnum.SUPPLIER_PHONE.getAttr(),phoneObj.getString(StringConstant.PHONE_TEL_ATTR));
        }
        // 供应商地址
        JSONObject addressObj = JsonHelperUtil.parseObject(dataObj.getString(SupplierEnum.ADDRESS.getAttr()));
        String formatAddress = getFormatAddress(addressObj);
        newData.put(AdditionalPrintAttrEnum.SUPPLIER_ADDRESS.getAttr(),formatAddress);
        newData.put(AdditionalPrintAttrEnum.SUPPLIER_ADDRESS.getAttr() + "_full",addressObj);
        // 供应商联系人及联系人电话
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(formDataGetDTO,formDataListDTO);
        formDataListDTO.setFormId(null);
        List<ConditionsEntityExt> conditionsEntityExtList = new ArrayList<>();
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(SupplierContactEnum.SUPPLIER_ID.getAttr());
        conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        conditionsEntityExt.setValue(Collections.singletonList(supplierId));
        conditionsEntityExt.setFieldType(FieldTypeEnum.TEXT.getType());
        conditionsEntityExtList.add(conditionsEntityExt);
        formDataListDTO.setConditions(conditionsEntityExtList);
        formDataListDTO.setBusinessType(RedundantTemplateTypeEnum.SUPPLIER_CONTACT.getCode());
        formDataListDTO.setFlowStatusIn(Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType()));
        PaasFormDataEsListVO paasFormDataEsListVO;
        try {
            formDataListDTO.setSearchSubForm(false);
            IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
            paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        } catch (Exception e) {
            e.printStackTrace();
            paasFormDataEsListVO = new PaasFormDataEsListVO();
        }
        List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();

        StringBuilder supplierContactBuilder = new StringBuilder();
        StringBuilder supplierContactPhoneBuilder = new StringBuilder();
        // 设置联系人及电话数据
        setSupplierContactDataES(paasFormDataESList, supplierContactBuilder, supplierContactPhoneBuilder);
        newData.put(AdditionalPrintAttrEnum.SUPPLIER_CONTACT_NAME.getAttr(),supplierContactBuilder.toString());
        newData.put(AdditionalPrintAttrEnum.SUPPLIER_CONTACT_PHONE.getAttr(),supplierContactPhoneBuilder.toString());
        // 供应商负责人
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", 0);
        param.put("supplierId", supplierId);
        param.put("corpid", corpid);
        param.put("isMain",1);
        List<UserTeamEntity> userTeamEntities = supplierUserModel.findBaseEntitys(param);
        StringBuilder supplierUserNameBuilder = new StringBuilder();
        setManagers(userTeamEntities, supplierUserNameBuilder);
        newData.put(AdditionalPrintAttrEnum.SUPPLIER_MANAGER_NAME.getAttr(),supplierUserNameBuilder.toString());

    }

    /**
     * 设置负责人名称
     * @param userTeamEntities 负责团队列表
     * @param supplierUserNameBuilder 封装名称
     */
    private void setManagers(List<UserTeamEntity> userTeamEntities, StringBuilder supplierUserNameBuilder) {
        for (UserTeamEntity userTeamEntity : userTeamEntities) {
            String userName = userTeamEntity.getUserName();
            if (StringUtil.isEmpty(userName)) {
                continue;
            }
            if (supplierUserNameBuilder.length() > 0) {
                supplierUserNameBuilder.append("，").append(userName);
            } else {
                supplierUserNameBuilder.append(userName);
            }
        }
    }

    /**
     * 供应商联系人及联系人电话
     * @param paasFormDataESList 供应商联系人列表
     * @param supplierContactBuilder 供应商联系人名称
     * @param supplierContactPhoneBuilder 供应商联系人电话
     */
    private void setSupplierContactDataES(List<PaasFormDataEntityExt> paasFormDataESList, StringBuilder supplierContactBuilder, StringBuilder supplierContactPhoneBuilder) {
        if (paasFormDataESList == null) {
            return;
        }
        for (PaasFormDataEntityExt paasFormDataEsEntity : paasFormDataESList) {
            JSONObject data = paasFormDataEsEntity.getData();
            if (data == null || data.isEmpty()) {
                continue;
            }
            String name = data.getString(SupplierContactEnum.NAME.getAttr());
            if (StringUtil.isEmpty(name)) {
                continue;
            }
            if (supplierContactBuilder.length() > 0) {
                supplierContactBuilder.append("，").append(name);
            } else {
                supplierContactBuilder.append(name);
            }
            JSONArray contactPhoneArray;
            try{
                contactPhoneArray = data.getJSONArray(SupplierContactEnum.PHONE.getAttr());
            } catch (Exception e) {
                contactPhoneArray = new JSONArray();
            }
            if (CollectionsUtil.isEmpty(contactPhoneArray)) {
                continue;
            }
            for (Object obj : contactPhoneArray){
                JSONObject phoneObj = (JSONObject)obj;
                String phoneNum = phoneObj.getString(StringConstant.PHONE_TEL_ATTR);
                if (StringUtil.isEmpty(phoneNum)) {
                    continue;
                }
                if (supplierContactPhoneBuilder.length() > 0) {
                    supplierContactPhoneBuilder.append(",").append(phoneNum);
                } else {
                    supplierContactPhoneBuilder.append(phoneNum);
                }
            }

        }

    }

    /**
     * 设置入库出库仓库负责人
     * @param corpid 公司id
     * @param data 旧数据
     * @param newData 新数据
     */
    private void setWarehouseManager(String corpid,JSONObject data, JSONObject newData,String intoAttr,String outAttr){
        JSONArray intoWarehouseArray = JsonHelperUtil.parseArray(data.getString(intoAttr));
        JSONArray outWarehouseArray = JsonHelperUtil.parseArray(data.getString(outAttr));
        if (intoWarehouseArray.isEmpty() || outWarehouseArray.isEmpty()) {
            return;
        }
        JSONObject intoWarehouseObj = intoWarehouseArray.getJSONObject(0);
        JSONObject outWarehouseObj = outWarehouseArray.getJSONObject(0);
        Long intoWarehouseId = StringUtil.StringToLong(intoWarehouseObj.getString(StringConstant.SAAS_LINK_BUSINESS_ID));
        Long outWarehouseId = StringUtil.StringToLong(outWarehouseObj.getString(StringConstant.SAAS_LINK_BUSINESS_ID));
        // 入库仓库负责人
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("warehouseId", intoWarehouseId);
        map.put("corpid",corpid);
        map.put("del",0);
        map.put("isMain",1);
        map.put("type",0);
        List<WarehouseUserEntity> intoWarehouseUserList = warehouseUserModel.findEntitys(map);
        StringBuilder intoManagerBuilder = new StringBuilder();
        setWarehouseUsers(intoWarehouseUserList, intoManagerBuilder);
        // 出库仓库负责人
        map.put("warehouseId", outWarehouseId);
        List<WarehouseUserEntity> outWarehouseUserList = warehouseUserModel.findEntitys(map);
        StringBuilder outManagerBuilder = new StringBuilder();
        setWarehouseUsers(outWarehouseUserList, outManagerBuilder);
        newData.put(AdditionalPrintAttrEnum.IN_USER_NAME.getAttr(),intoManagerBuilder.toString());
        newData.put(AdditionalPrintAttrEnum.OUT_USER_NAME.getAttr(),outManagerBuilder.toString());
    }

    /**
     * 设置仓库负责人名称
     * @param warehouseUserList 负责团队列表
     * @param userNameBuilder 封装名称
     */
    private void setWarehouseUsers(List<WarehouseUserEntity> warehouseUserList, StringBuilder userNameBuilder) {
        for (WarehouseUserEntity warehouseUser : warehouseUserList) {
            String relationName = warehouseUser.getRelationName();
            if (StringUtil.isEmpty(relationName)) {
                continue;
            }
            if (userNameBuilder.length() > 0) {
                userNameBuilder.append("，").append(relationName);
            } else {
                userNameBuilder.append(relationName);
            }
        }
    }

    /**
     * 设置子表单- 产品 的数据格式
     * @param corpid 公司id
     * @param data 原始数据
     * @param newData 新数据
     * @param productAttr 产品attr
     * @param xbbRefType 业务类型
     * @param explainMap 解释map
     */
    private void setTabProductsAttr(FormDataGetDTO formDataGetDTO,String corpid, JSONObject data, JSONObject newData, String productAttr, Integer xbbRefType, Map<String, FieldAttrEntity> explainMap) throws XbbException{
        String productResult;
        DetailTabDataGetDTO detailTabDataGetDTO = new DetailTabDataGetDTO();
        BeanUtil.copyProperties(formDataGetDTO,detailTabDataGetDTO);
        detailTabDataGetDTO.setAttr(productAttr);
        detailTabDataGetDTO.setPage(1);
        PaasConfigGetDTO paasConfigGetDTO = new PaasConfigGetDTO(corpid);
        PaasConfigGetVO paasConfiggetVO = paasConfigService.getSubFormConfig(paasConfigGetDTO);
        detailTabDataGetDTO.setPageSize(paasConfiggetVO.getSelectProductRowNum());
        try {
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            productResult = formFeignClient.getRelationProductList(detailTabDataGetDTO, lang);
        } catch (Exception e) {
            LOG.error("获取产品数据报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nStringConstant.PRODUCT_DATA_ERROR);
        }
        JSONObject productResultObj = JsonHelperUtil.parseObject(productResult);
        if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)productResultObj.get(StringConstant.CODE)) {
            throw new XbbException(productResultObj.getIntValue(StringConstant.CODE),productResultObj.getString(StringConstant.KEY_ERROR_MSG));
        }
        RelationProductListVO relationProductListVO = JsonHelperUtil.parseObject(productResultObj.getString(StringConstant.RESULT),RelationProductListVO.class);
        List<FieldAttrEntity> headList = relationProductListVO.getHeadList();
        List<PaasFormDataEntityExt> formDataList = relationProductListVO.getFormDataList();
        List<Integer> analysisFieldType = new ArrayList<>();
        analysisFieldType.add(FieldTypeEnum.LINK_DATA.getType());
        analysisFieldType.add(FieldTypeEnum.LINK_BUSINESS_SINGLE.getType());
        analysisFieldType.add(FieldTypeEnum.LINK_BUSINESS_MULTI.getType());
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        handlerExplainDTO.setLoginUser(formDataGetDTO.getLoginUser());
        handlerExplainDTO.setUserId(formDataGetDTO.getUserId());
        for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
            JSONObject productData = paasFormDataEntityExt.getData();
            handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(Collections.singletonList(paasFormDataEntityExt.getOwnerId()));
            for (FieldAttrEntity fieldAttrEntity : headList) {
                StringBuilder name = new StringBuilder("");
                /* if (!ExplainUtil.isEditableOfScope(fieldAttrEntity, handlerExplainDTO)) {
                    continue;
                } */
                String attr = fieldAttrEntity.getAttr();
                if (analysisFieldType.contains(fieldAttrEntity.getFieldType())) {
                    JSONArray jsonArray = productData.getJSONArray(attr);
                    if (Objects.isNull(jsonArray)) {
                        continue;
                    }
                    for (int i = 0; i < jsonArray.size(); i ++) {
                        name.append(jsonArray.getJSONObject(i).getString(StringConstant.SAAS_LINK_BUSINESS_NAME)).append(StringConstant.COMMA);
                    }
                    if (StringUtil.isNotEmpty(name.toString())) {
                        productData.put(attr, name.substring(0, name.length() - 1));
                    }
                } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.DATETIME.getType())) {
                    Integer time = productData.getInteger(attr);
                    if (Objects.equals(0, time)) {
                        productData.remove(attr);
                    } else if (Objects.nonNull(time)) {
                        productData.put(attr, DateTimeUtil.getDateStringEpochSecond(productData.getInteger(attr)));
                    }
                }else if(Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COMBO.getType()) ||Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.RADIO_GROUP.getType())){
                    if (Objects.equals(fieldAttrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr())
                            || Objects.equals(fieldAttrEntity.getSaasAttr(), SelectProductEnum.UNIT.getSaasAttr())
                            || Objects.equals(fieldAttrEntity.getSaasAttr(), WaitOutstockEnum.UNIT.getSaasAttr())){

                    }else{
                        JSONObject jsonObject = productData.getJSONObject(attr);
                        if (Objects.nonNull(jsonObject)){
                            productData.put(attr, jsonObject.getString(StringConstant.TEXT));
                        }
                    }
                }else if(Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COMBO_CHECK.getType()) || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.CHECKBOX_GROUP.getType())){
                    if (Objects.equals(fieldAttrEntity.getSaasAttr(), ProductEnum.UNIT.getSaasAttr())
                            || Objects.equals(fieldAttrEntity.getSaasAttr(), SelectProductEnum.UNIT.getSaasAttr())
                            || Objects.equals(fieldAttrEntity.getSaasAttr(), WaitOutstockEnum.UNIT.getSaasAttr())){

                    }else{
                        JSONArray jsonArray = productData.getJSONArray(attr);
                        StringBuilder sb = new StringBuilder();
                        if (Objects.nonNull(jsonArray)){
                            for (Object o : jsonArray) {
                                JSONObject jsonObject = (JSONObject) o;
                                if (sb.length() != 0){
                                    sb.append(StringConstant.COMMA);
                                }
                                sb.append(jsonObject.getString(StringConstant.TEXT));
                            }
                        }
                        productData.put(attr, sb.toString());
                    }
                }
                // BOM和盘点也需要转换
                List<Integer> stockList = new ArrayList<>(StockConstant.MULTI_UNIT_TYPE_LIST);
                stockList.add(XbbRefTypeEnum.BOM_BILL.getCode());
                stockList.add(XbbRefTypeEnum.INVENTORY.getCode());
                if (Objects.equals(attr, SelectProductEnum.NUM.getAttr()) && Objects.equals(fieldAttrEntity.getIsRedundant(), 0) && stockList.contains(xbbRefType)) {
                    productData.put(SelectProductEnum.BUSINESS_NUM.getAttr(),productData.getDouble(SelectProductEnum.NUM.getAttr()));
                    productData.put(SelectProductEnum.BUSINESS_UNIT.getAttr(),productData.getString(SelectProductEnum.UNIT.getAttr()));
                    boolean isMulti = Objects.equals(productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr()), 1);
                    if (isMulti) {
                        JSONArray transformUnitRate = productData.getJSONArray(ProductConstant.TRANSFORM_UNIT_RATE);
                        if (transformUnitRate != null) {
                            String baseName = transformUnitRate.getJSONObject(0).getString(MultiUnitConstant.MULTI_UNIT_TEXT);
                            for (int i = 0; i < transformUnitRate.size(); i++) {
                                JSONObject transformUnitObj = transformUnitRate.getJSONObject(i);
                                if (Objects.equals(productData.getString(SelectProductEnum.UNIT.getAttr()), transformUnitObj.getString(MultiUnitConstant.MULTI_UNIT_TEXT))) {
                                    Double rate = transformUnitObj.getDouble(MultiUnitConstant.RATE);
                                    productData.put(SelectProductEnum.NUM.getAttr(), Arith.mul(rate, productData.getDouble(SelectProductEnum.BUSINESS_NUM.getAttr())));
                                    productData.put(SelectProductEnum.UNIT.getAttr(), baseName);
                                    break;
                                }
                            }
                        }
                    }
                }
                // 进销存关联产品的库存数量、产品单价、产品成本展示千分位格式
//                if (SelectProductEnum.STOCK.getAttr().equals(fieldAttrEntity.getAttr()) || SelectProductEnum.COST.getAttr().equals(fieldAttrEntity.getAttr()) || SelectProductEnum.PRICE.getAttr().equals(fieldAttrEntity.getAttr())) {
                // 启用金额
                if (BasicConstant.ONE.equals(fieldAttrEntity.getAmountFlag())) {
                    Integer accuracy = fieldAttrEntity.getAccuracy();
                    // 仅允许填写整数，精度为0
                    accuracy = Objects.equals(fieldAttrEntity.getIntegerOnly(), BasicConstant.ONE) ? BasicConstant.ZERO : accuracy;
                    String value = productData.getString(attr);
                    productData.put(attr, AttrDecimalPrecisionHelper.parseThousandth(value, accuracy));
                }
//                }
            }
        }
        JSONObject newProduct = new JSONObject();
        JSONArray productArray = new JSONArray();
        for (PaasFormDataEntityExt paasFormDataEntityExt : formDataList) {
            JSONObject productData = paasFormDataEntityExt.getData();
            JSONObject oldData = new JSONObject();
            for (String key : productData.keySet()) {
                if (Objects.nonNull(ProductPrintHelpEnum.getOldAttrByNewAttr(key))) {
                    if (!productData.containsKey(ProductPrintHelpEnum.getOldAttrByNewAttr(key)) ) {
                        oldData.put(ProductPrintHelpEnum.getOldAttrByNewAttr(key), productData.get(key));
                    }
                }
            }
            productData.putAll(oldData);
            productArray.add(productData);
        }
        newProduct.put(PrintConstant.ATTRLIST, productArray);
        String productSummary;
        List<Integer> outstckTypes = Arrays.asList(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.OUTSTOCK.getCode(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(), XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
        if (outstckTypes.contains(xbbRefType) || Objects.equals(xbbRefType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.PURCHASE.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.QUOTATION.getCode())) {
            try {
                Locale locale = LocaleContextHolder.getLocale();
                String lang = locale.toString();
                productSummary = formFeignClient.getProductSummaryList(detailTabDataGetDTO, lang);
            } catch (Exception e) {
                LOG.error("获取产品汇总数据报错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(ErrorMessageConstant.PRODUCT_SUMMARY_DATA_ERROR));
            }
            JSONObject summaryResultObj = JsonHelperUtil.parseObject(productSummary);
            if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)summaryResultObj.get(StringConstant.CODE)) {
                throw new XbbException(summaryResultObj.getIntValue(StringConstant.CODE),summaryResultObj.getString(StringConstant.KEY_ERROR_MSG));
            }
            ProductSummaryVO productSummaryVO = JsonHelperUtil.parseObject(summaryResultObj.getString(StringConstant.RESULT),ProductSummaryVO.class);
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(xbbRefType);
            switch (xbbRefTypeEnum){
                case CONTRACT:
                    dealProductSpecialAttr(corpid, newProduct, productSummaryVO, explainMap.get(ContractEnum.PRODUCT_TOTAL.getAttr()));
                    break;
                case QUOTATION:
                    dealQuoTationProductSpecialAttr(corpid, newProduct, productSummaryVO, explainMap.get(QuotationEnum.PRODUCT_TOTAL.getAttr()));
                    break;
                case SALES_OPPORTUNITY:
                    dealSaleSpecialAttr(corpid, newProduct, productSummaryVO, explainMap.get(SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr()));
                    break;
                case CONTRACT_OUTSTOCK:
                    dealContractOutstock(corpid, newProduct, productSummaryVO, XbbRefTypeEnum.CONTRACT_OUTSTOCK, null, ContractOutstockEnum.PRODUCT.getAttr());
                    break;
                // case OTHER_OUTSTOCK:
                //     dealJxcProductSpecialAttr(corpid, newProduct, productSummaryVO, XbbRefTypeEnum.OTHER_OUTSTOCK, null, OutstockProductEnum.PRODUCT.getAttr());
                //     break;
                case PURCHASE:
                    dealJxcProductSpecialAttr(corpid, newProduct, productSummaryVO, XbbRefTypeEnum.PURCHASE, null, OutstockProductEnum.PRODUCT.getAttr());
                    break;
                default:
                    // 出库单产品
                    JSONObject others = productSummaryVO.getOthers();
                    if (others.getBoolean("hideCost") != null && others.getBoolean("hideCost")){
                        others.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias()," *****");
                    }

                    newProduct.put("sumAttrList",others);
                    break;

            }
        }

        /**
         * if (Objects.equals(xbbRefType, XbbRefTypeEnum.OUTSTOCK.getCode())) {
         // 16660 【出库单】打印销售出库类型的出库单未正确展示单价
         JSONArray productArray = productObj.getJSONArray("productList");
         for (int i=0; i<productArray.size(); i++) {
         JSONObject productItemObj = productArray.getJSONObject(i);
         JSONArray productAttrArray = productItemObj.getJSONArray("result");
         for (int j=0; j<productAttrArray.size(); j++) {
         JSONObject productAttrObj = productAttrArray.getJSONObject(j);
         if (Objects.equals(productAttrObj.getString("attr"), OutstockSaleRelativeConstantEnum.PRICE.getAlias())) {
         productAttrObj.put("attr", RelativeProductEnum.PRODUCT_PRICE.getSaasAttr());
         break;
         }
         }
         }
         }
         */
        // 其他表单的产品处理
        /*if (productObj == null) {
            return;
        }
        // 获取产品列表
        JSONObject newProduct = getProductList(productObj);

        if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(),xbbRefType)) {
            // 产品售价合计
            JSONObject others = (JSONObject) productObj.get(BusinessConstant.OTHERS);

            String amountStr = (String) others.get(BusinessConstant.TOTAL_PRODUCT_MONEY);
            JSONObject surcharge = new JSONObject();
            if (!Objects.equals(amountStr, StringConstant.INVISIBLE_VALUE)) {
                double totalProductMoney = Double.parseDouble(amountStr.replaceAll(",", ""));
                String digitUpperMoney = MoneyUtil.doubleToUppercase(totalProductMoney);
                amountStr = digitUpperMoney + " " + amountStr + MoneyUnitEnum.YUAN.getUnit();
            }
            surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
            newProduct.put("sumAttrList",surcharge);
        } else if (Objects.equals(XbbRefTypeEnum.OUTSTOCK.getCode(), xbbRefType)) {
            // 出库单产品
            JSONObject others = JsonHelperUtil.parseObject(productObj.getString("others"));
            if (others.getBoolean("hideCost") != null && others.getBoolean("hideCost")){
                others.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias()," *****");
            }
            if (others.containsKey(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias())) {
                Object outProductCostTotal = others.get(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias());
                others.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias(), outProductCostTotal + MoneyUnitEnum.YUAN.getUnit());
            }
            // 金额大写
            if (others.containsKey(OutstockSaleRelativeConstantEnum.SALE_PRICE_AMOUNT.getAlias())) {
                String priceTotal = others.getString(OutstockSaleRelativeConstantEnum.SALE_PRICE_AMOUNT.getAlias());
                double totalPriceMoney = Double.parseDouble(priceTotal.replaceAll(",", ""));
                String digitUpperMoney = MoneyUtil.doubleToUppercase(totalPriceMoney);
                priceTotal = digitUpperMoney + " " + priceTotal + MoneyUnitEnum.YUAN.getUnit();
                others.put(OutstockSaleRelativeConstantEnum.SALE_PRICE_AMOUNT.getAlias(), priceTotal);
            }
            newProduct.put("sumAttrList",others);
        } else  {
            JSONObject others = JsonHelperUtil.parseObject(productObj.getString("others"));
            if (others.getBoolean("hideCost") != null && others.getBoolean("hideCost")){
                others.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias()," *****");
            }
            newProduct.put("sumAttrList",others);
        }*/
        newData.put(productAttr,newProduct);
    }


    private void dealSaleSpecialAttr(String corpid, JSONObject newProduct, ProductSummaryVO productSummaryVO, FieldAttrEntity costField) throws XbbException {
        String bigMoney;
        String smallMoney;
        JSONObject others = productSummaryVO.getOthers();
        Boolean hidePrice = others.getBoolean("hidePrice");
        if (Objects.isNull(hidePrice)){
            hidePrice = false;
        }
        JSONObject surcharge = new JSONObject();
        String amountStr = "";
        if (!hidePrice) {
            Double amount;
            try {
                amount = others.getDouble("amount");
                if (Objects.isNull(amount)){
                    amount = others.getDouble("outProductCostTotal");
                }
            } catch (Exception e) {
                amount = null;
            }
            if (Objects.nonNull(amount)) {
                // 获取产品合计精度
//                ProductFieldPojo costField = proFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_PRICE,ProductEnum.PRICE.getAttr(), corpid);
                Integer accuracy = BasicConstant.TWO;
                if (Objects.nonNull(costField)) {
                    accuracy = costField.getAccuracy();
                }
                // 先算精度
                amount = attrDecimalPrecisionHelper.setPrecision(amount, accuracy);
                String digitUpperMoney = MoneyUtil.doubleToUppercase(amount);
                amountStr = digitUpperMoney + " " + AttrDecimalPrecisionHelper.parseThousandth(amount, accuracy);
                bigMoney = digitUpperMoney;
                smallMoney = AttrDecimalPrecisionHelper.parseThousandth(amount, accuracy).toString();
            } else {
                amountStr = BasicConstant.NULL_SHOW_STR;
                bigMoney = BasicConstant.NULL_SHOW_STR;
                smallMoney = BasicConstant.NULL_SHOW_STR;
            }
        } else {
            amountStr = StringConstant.INVISIBLE_VALUE;
            bigMoney = StringConstant.INVISIBLE_VALUE;
            smallMoney = StringConstant.INVISIBLE_VALUE;
        }
        surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
        surcharge.put(BusinessConstant.DIGIT_UPPER_MONEY, bigMoney);
        surcharge.put(BusinessConstant.SMALL_MONEY, smallMoney);
        surcharge.putAll(others);
        newProduct.put("sumAttrList", surcharge);
    }
    private void dealQuoTationProductSpecialAttr(String corpid, JSONObject newProduct, ProductSummaryVO productSummaryVO, FieldAttrEntity productTotalField) throws XbbException {
        String bigMoney;
        String smallMoney;
        JSONObject others = productSummaryVO.getOthers();
        Boolean hidePrice = others.getBoolean("hidePrice");
        if (Objects.isNull(hidePrice)){
            hidePrice = false;
        }
        JSONObject surcharge = new JSONObject();
        String amountStr = "";
        if (!hidePrice) {
            Double amount;
            try {
                amount = others.getDouble("amount");
                if (Objects.isNull(amount)){
                    amount = others.getDouble("outProductCostTotal");
                }
            } catch (Exception e) {
                amount = null;
            }
            if (Objects.nonNull(amount)) {
                // 获取产品合计精度
//                PaasFormExplainEntity contractExplainEntity = paasFormExplainModel.getByBusinessType(contract.getCode(), corpid);
//                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(contractExplainEntity.getExplains(), attr);
//                FieldAttrEntity productTotalField = explainMap.get(attr2);
                Integer accuracy = BasicConstant.TWO;
                if (Objects.nonNull(productTotalField)) {
                    accuracy = productTotalField.getAccuracy();
                }
                // 先算精度
                amount = attrDecimalPrecisionHelper.setPrecision(amount, accuracy);
                String digitUpperMoney = MoneyUtil.doubleToUppercase(amount);
                amountStr = digitUpperMoney + " " + AttrDecimalPrecisionHelper.parseThousandth(amount, accuracy);
                bigMoney = digitUpperMoney;
                smallMoney = AttrDecimalPrecisionHelper.parseThousandth(amount, accuracy).toString();
            } else {
                amountStr = BasicConstant.NULL_SHOW_STR;
                bigMoney = BasicConstant.NULL_SHOW_STR;
                smallMoney = BasicConstant.NULL_SHOW_STR;
            }
        } else {
            amountStr = StringConstant.INVISIBLE_VALUE;
            bigMoney = StringConstant.INVISIBLE_VALUE;
            smallMoney = StringConstant.INVISIBLE_VALUE;
        }
        surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
        surcharge.put(BusinessConstant.DIGIT_UPPER_MONEY, bigMoney);
        surcharge.put(BusinessConstant.SMALL_MONEY, smallMoney);
        surcharge.putAll(others);
        newProduct.put("sumAttrList", surcharge);
    }


    private void dealProductSpecialAttr(String corpid, JSONObject newProduct, ProductSummaryVO productSummaryVO, FieldAttrEntity productTotalField) throws XbbException {
        String bigMoney;
        String smallMoney;
        JSONObject others = productSummaryVO.getOthers();
        Boolean hidePrice = others.getBoolean("hidePrice");
        if (Objects.isNull(hidePrice)){
            hidePrice = false;
        }
        JSONObject surcharge = new JSONObject();
        String amountStr = "";
        if (!hidePrice) {
            Double amount;
            try {
                amount = others.getDouble("amount");
                if (Objects.isNull(amount)){
                    amount = others.getDouble("outProductCostTotal");
                }
            } catch (Exception e) {
                amount = null;
            }
            if (Objects.nonNull(amount)) {
                Integer accuracy = BasicConstant.TWO;
                if (Objects.nonNull(productTotalField)) {
                    accuracy = productTotalField.getAccuracy();
                }
                // 先算精度
                amount = attrDecimalPrecisionHelper.setPrecision(amount, accuracy);
                String digitUpperMoney = MoneyUtil.doubleToUppercase(amount);
                amountStr = digitUpperMoney + " " + AttrDecimalPrecisionHelper.parseThousandth(amount, accuracy);
                bigMoney = digitUpperMoney;
                smallMoney = AttrDecimalPrecisionHelper.parseThousandth(amount, accuracy).toString();
            } else {
                amountStr = BasicConstant.NULL_SHOW_STR;
                bigMoney = BasicConstant.NULL_SHOW_STR;
                smallMoney = BasicConstant.NULL_SHOW_STR;
            }
        } else {
            amountStr = StringConstant.INVISIBLE_VALUE;
            bigMoney = StringConstant.INVISIBLE_VALUE;
            smallMoney = StringConstant.INVISIBLE_VALUE;
        }
        surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
        surcharge.put(BusinessConstant.DIGIT_UPPER_MONEY, bigMoney);
        surcharge.put(BusinessConstant.SMALL_MONEY, smallMoney);
        surcharge.putAll(others);
        newProduct.put("sumAttrList", surcharge);
    }

    private void dealContractOutstock(String corpid, JSONObject newProduct, ProductSummaryVO productSummaryVO, XbbRefTypeEnum contract, String attr, String attr2) throws XbbException {
        String bigMoney;
        Double smallMoney;
        JSONObject others = productSummaryVO.getOthers();
        Boolean hidePrice = others.getBoolean("hidePrice");
        if (Objects.isNull(hidePrice)){
            hidePrice = false;
        }
        JSONObject surcharge = new JSONObject();
        String amountStr = "";
        if (!hidePrice) {
            Double amount;
            try {
                amount = others.getDouble("amount");
                if (Objects.equals(contract, XbbRefTypeEnum.CONTRACT_OUTSTOCK)){
                    amount = others.getDouble("priceTotal");
                }
            } catch (Exception e) {
                amount = null;
            }
            if (Objects.nonNull(amount)) {
                // 获取产品合计精度
                PaasFormExplainEntity contractExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(contractExplainEntity.getExplains(), null);
                FieldAttrEntity numFieldAttrEntity = explainMap.getOrDefault(ProductEnum.PRICE.getAttr(), new FieldAttrEntity());
                Integer numPrecision = BasicConstant.TWO;
                if (Objects.nonNull(numFieldAttrEntity)) {
                    numPrecision = numFieldAttrEntity.getAccuracy();
                }
                // 先算精度
                amount = attrDecimalPrecisionHelper.setPrecision(amount, numPrecision);
                String digitUpperMoney = MoneyUtil.doubleToUppercase(amount);
                amountStr = digitUpperMoney + " " + amount;
                bigMoney = digitUpperMoney;
                smallMoney = amount;
                surcharge.put(BusinessConstant.SMALL_MONEY, smallMoney);
            } else {
                amountStr = BasicConstant.NULL_SHOW_STR;
                bigMoney = BasicConstant.NULL_SHOW_STR;
            }
        } else {
            amountStr = StringConstant.INVISIBLE_VALUE;
            bigMoney = StringConstant.INVISIBLE_VALUE;
        }
        surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
        surcharge.put(BusinessConstant.DIGIT_UPPER_MONEY, bigMoney);
        surcharge.putAll(others);
        newProduct.put("sumAttrList", surcharge);
    }
    private void dealJxcProductSpecialAttr(String corpid, JSONObject newProduct, ProductSummaryVO productSummaryVO, XbbRefTypeEnum contract, String attr, String attr2) throws XbbException {
        String bigMoney;
        String smallMoney;
        JSONObject others = productSummaryVO.getOthers();
        Boolean hidePrice = others.getBoolean("hidePrice");
        if (Objects.isNull(hidePrice)){
            hidePrice = false;
        }
        JSONObject surcharge = new JSONObject();
        String amountStr = "";
        if (!hidePrice) {
            Double amount;
            try {
                amount = others.getDouble("amount");
                if (Objects.equals(contract, XbbRefTypeEnum.CONTRACT_OUTSTOCK)){
                    amount = others.getDouble("priceTotal");
                }
                if (Objects.isNull(amount)){
                    amount = others.getDouble("outProductCostTotal");
                }
            } catch (Exception e) {
                amount = null;
            }
            if (Objects.nonNull(amount)) {
                // 获取产品合计精度
                PaasFormExplainEntity contractExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(contractExplainEntity.getExplains(), null);
                FieldAttrEntity numFieldAttrEntity = explainMap.getOrDefault(ProductEnum.STOCK.getAttr(), new FieldAttrEntity());
                Integer numPrecision = BasicConstant.TWO;
                if (Objects.nonNull(numFieldAttrEntity)) {
                    numPrecision = numFieldAttrEntity.getAccuracy();
                }
                // 先算精度
                amount = attrDecimalPrecisionHelper.setPrecision(amount, numPrecision);
                String digitUpperMoney = MoneyUtil.doubleToUppercase(amount);
                amountStr = digitUpperMoney + " " + amount;
                bigMoney = digitUpperMoney;
                smallMoney = attrDecimalPrecisionHelper.setPrecision(amount, numPrecision).toString();
            } else {
                amountStr = BasicConstant.NULL_SHOW_STR;
                bigMoney = BasicConstant.NULL_SHOW_STR;
                smallMoney = BasicConstant.NULL_SHOW_STR;
            }
        } else {
            amountStr = StringConstant.INVISIBLE_VALUE;
            bigMoney = StringConstant.INVISIBLE_VALUE;
            smallMoney = StringConstant.INVISIBLE_VALUE;
        }
        surcharge.put(BusinessConstant.SMALL_MONEY, smallMoney);
        surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
        surcharge.put(BusinessConstant.DIGIT_UPPER_MONEY, bigMoney);
        surcharge.putAll(others);
        newProduct.put("sumAttrList", surcharge);
    }
    /**
     * 设置打印产品列表
     * @param productObj 产品对象
     * @return newProduct 新的格式化好的格式
     */
    private JSONObject getProductList(JSONObject productObj) {
        JSONArray productList = JsonHelperUtil.parseArray(productObj.getString(StringConstant.PRODUCT_LIST));
        JSONArray newResultArray = new JSONArray();
        JSONObject newProduct = new JSONObject();
        // 遍历列表，封装格式给前端
        for (Object obj : productList) {
            JSONObject pObj = (JSONObject)obj;
            JSONArray result = JsonHelperUtil.parseArray(pObj.getString(StringConstant.RESULT));
            JSONArray thumbnail = JsonHelperUtil.parseArray(pObj.getString(RelativeProductEnum.THUMBNAIL.getSaasAttr()));
            // 添加产品图片
            JSONObject newResult = new JSONObject();
            if (!thumbnail.isEmpty()) {
                newResult.put(RelativeProductEnum.THUMBNAIL.getAttr(),thumbnail.get(0));
            }
            // 是否有成本字段
            boolean hasCost = false;
            for (Object rObj : result) {
                JSONObject retObj = (JSONObject)rObj;
                String attr = retObj.getString(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG);
                String attrValue = retObj.getString(StringConstant.ATTR_VALUE);
                boolean hideCost = retObj.getBoolean("hideCost") == null ? false : retObj.getBoolean("hideCost");
                RelativeProductEnum relativeProductEnum = RelativeProductEnum.getBySaasAttr(attr);
                if (RelativeProductEnum.WAREHOUSE == relativeProductEnum) {
                    // 仓库字段 存的Object
                    JSONObject valueObj = JsonHelperUtil.parseObject(attrValue);
                    attrValue = valueObj.getString(StringConstant.VALUE);
                }
                if (hideCost) {
                    attrValue = "*****";
                }
                newResult.put(attr,attrValue);
                if (StringConstant.PRODUCT_COST.equals(attr)) {
                    hasCost = true;
                }
            }
            if (!hasCost) {
                // 如果没有传成本字段，可能是隐藏成本，所以加一个***
                newResult.put(StringConstant.PRODUCT_COST,"*****");
            }
            newResultArray.add(newResult);
        }
        newProduct.put(PrintConstant.ATTRLIST,newResultArray);
        return newProduct;
    }

    /**
     * 设置工作报告业绩数据 的数据格式
     * @param data 原始数据
     * @param newData 新数据
     * @param statisticAttr attr
     * @param workReportDetailVO 工作报告统计详情
     */
    private void setWorkReportStatisticAttr( JSONObject data, JSONObject newData, String statisticAttr, WorkReportDetailVO workReportDetailVO) {

        List<WorkReportDetailStatisticResultPojo> statisticResultList = workReportDetailVO.getStatisticResultList();
        Map<String, WorkReportDetailStatisticResultPojo> statisticResultPojoMap = new HashMap<>(statisticResultList.size());
        statisticResultList.forEach((item)->{
            statisticResultPojoMap.put(item.getAttr(), item);
        });

        List <StatisticOptionEnum> allEnum = StatisticOptionEnum.getAllEnum();
        JSONArray resultArray = new JSONArray();
        JSONObject resultObj = new JSONObject();
        for (StatisticOptionEnum optionEnum : allEnum ) {
            if (statisticResultPojoMap.get(optionEnum.getAttr()) != null) {
                resultObj.put(optionEnum.getAttr(),statisticResultPojoMap.get(optionEnum.getAttr()).getValue());
            }
        }
        resultArray.add(resultObj);
        JSONObject result = new JSONObject();
        result.put(PrintConstant.ATTRLIST,resultArray);
        newData.put(statisticAttr,result);
    }

    /**
     * 设置对象数组为 逗号隔开字符串 展示
     * @param array 数组
     * @param attr 字段
     * @return 格式后字符串
     */
    private String setJsonArrayStr(JSONArray array,String attr){
        StringBuilder sb = new StringBuilder();
        for (Object obj : array) {
            if (!(obj instanceof JSONObject)) {
                // 不是json跳过
                continue;
            }
            JSONObject businessObj = (JSONObject)obj;
            if (sb.length() > 0) {
                sb.append("，").append(businessObj.getString(attr));
            } else{
                sb.append(businessObj.getString(attr));
            }
        }
        return sb.toString();
    }

    /**
     * 设置字符串数组为 逗号隔开字符串 展示
     * @param array 数组
     * @return 格式后字符串
     */
    private String setStringArrayStr(JSONArray array){
        StringBuilder comboSb = new StringBuilder();
        for (Object obj: array) {
            String comboStr = "";
            if (obj instanceof  String) {
                comboStr = (String)obj;
            } else if (obj instanceof  Long || obj instanceof  Integer) {
                comboStr = obj.toString();
            } else if (Objects.nonNull(obj) && obj instanceof Map && ((Map) obj).containsKey("text")) {
                JSONObject jsonObject = (JSONObject) obj;
                comboStr = jsonObject.getString("text");
            }
            if (comboSb.length() > 0) {
                comboSb.append("，").append(comboStr);
            } else {
                comboSb.append(comboStr);
            }
        }
        return comboSb.toString();
    }

    /**
     * 处理回款单明细
     *
     * @param newData 回款单数据
     * @param amountDetail 回款单明细数据
     * @author 徐俊杰
     * @date 2019/12/4 11:06
     * @since v1.0
     */
    private void disposePaymentSheetAmount(JSONObject newData, JSONArray amountDetail) {
        JSONObject amountJSON = new JSONObject();
        //处理子回款单
        JSONArray attrList = new JSONArray();
        String type = newData.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
        for (int i = 0; i < amountDetail.size(); i++) {
            JSONObject attr = new JSONObject();
            JSONObject detail = amountDetail.getJSONObject(i);
            //关联合同
            String contractAttr = PrintPaymentSheetAmountEnum.CONTRACT.getAttr();
            String contractName = paymentSheetAmountJSONArray(detail, contractAttr);
            attr.put(contractAttr, contractName);
            //关联应收款
            String paymentAttr = PrintPaymentSheetAmountEnum.PAYMENT.getAttr();
            String paymentName = paymentSheetAmountJSONArray(detail, paymentAttr);
            attr.put(paymentAttr, paymentName);
            //归属人
            String belongIdAttr = PrintPaymentSheetAmountEnum.BELONG_ID.getAttr();
            String belongIdName = paymentSheetAmountJSONArray(detail, belongIdAttr);
            attr.put(belongIdAttr, belongIdName);
            //回款金额
            String amountAttr;
            if (SheetTypeEnum.onlyWriteOffAmount(type)) {
                amountAttr = PrintPaymentSheetAmountEnum.WRITE_OFF_AMOUNT.getAttr();
            } else {
                amountAttr = PrintPaymentSheetAmountEnum.AMOUNT.getAttr();
            }
            String amount = detail.getString(amountAttr);
            attr.put(amountAttr, amount);
            attrList.add(attr);
        }
        amountJSON.put(PrintConstant.ATTRLIST, attrList);
        String amountAttr;
        if (SheetTypeEnum.onlyWriteOffAmount(type)) {
            amountAttr = PrintSpecialAttrEnum.PAYMENT_SHEET_WRITE_OFF_AMOUNT_DETAIL.getAttr();
        } else {
            amountAttr = PrintSpecialAttrEnum.PAYMENT_SHEET_AMOUNT_DETAIL.getAttr();
        }
        //包装数据
        newData.put(amountAttr, amountJSON);
    }

    /**
     * 处理付款单明细
     *
     * @param newData 付款单数据
     * @param amountDetail 付款单明细数据
     * @author 徐俊杰
     * @date 2020/3/21 16:49
     * @since v1.0
     */
    private void disposePaySheetAmount(JSONObject newData, JSONArray amountDetail) {
        JSONObject amountJSON = new JSONObject();
        //处理子付款单
        JSONArray attrList = new JSONArray();
        String type = newData.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
        for (int i = 0; i < amountDetail.size(); i++) {
            JSONObject attr = new JSONObject();
            JSONObject detail = amountDetail.getJSONObject(i);
            //关联采购合同
            String purchaseAttr = PrintPaySheetAmountEnum.PURCHASE.getAttr();
            String purchaseName = paymentSheetAmountJSONArray(detail, purchaseAttr);
            attr.put(purchaseAttr, purchaseName);
            //关联付款计划
            String payPlanAttr = PrintPaySheetAmountEnum.PAY_PLAN.getAttr();
            String payPlanName = paymentSheetAmountJSONArray(detail, payPlanAttr);
            attr.put(payPlanAttr, payPlanName);
            //归属人
            String belongIdAttr = PrintPaySheetAmountEnum.BELONG_ID.getAttr();
            String belongIdName = paymentSheetAmountJSONArray(detail, belongIdAttr);
            attr.put(belongIdAttr, belongIdName);
            //付款金额
            String amountAttr;
            if (Objects.equals(PaySheetTypeEnum.WRITE_OFF_PREPAY.getName(), type)) {
                amountAttr = PrintPaySheetAmountEnum.WRITE_OFF_AMOUNT.getAttr();
            } else {
                amountAttr = PrintPaySheetAmountEnum.AMOUNT.getAttr();
            }
            String amount = detail.getString(amountAttr);
            attr.put(amountAttr, amount);
            attrList.add(attr);
        }
        amountJSON.put(PrintConstant.ATTRLIST, attrList);
        String amountAttr;
        if (Objects.equals(PaySheetTypeEnum.WRITE_OFF_PREPAY.getName(), type)) {
            amountAttr = PrintSpecialAttrEnum.PAY_SHEET_WRITE_OFF_AMOUNT_DETAIL.getAttr();
        } else {
            amountAttr = PrintSpecialAttrEnum.PAY_SHEET_AMOUNT_DETAIL.getAttr();
        }
        //包装数据
        newData.put(amountAttr, amountJSON);
    }

    /**
     * 处理回款单明细的内部字段
     *
     * @param detail 回款单明细数据
     * @param attr 字段名称
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2019/12/4 11:07
     * @since v1.0
     */
    private String paymentSheetAmountJSONArray(JSONObject detail, String attr) {
        JSONArray array = detail.getJSONArray(attr);
        StringBuilder nameStr = new StringBuilder();
        if (array != null) {
            for (int j = 0; j < array.size(); j++) {
                String name;
                try {
                    JSONObject item = array.getJSONObject(j);
                    name = item.getString("name");
                } catch (Exception e) {
                    name = "";
                }
                nameStr.append(name);
            }
        }
        return nameStr.toString();
    }

    /**
     * 处理销项发票明细
     *
     * @param newData 发票数据
     * @param amountDetail 发票明细数据
     * @author 徐俊杰
     * @date 2019/12/6 14:27
     * @since v1.0
     */
    private void disposeInvoiceTotalMoney(JSONObject newData, JSONArray amountDetail) {
        List<InvoiceAmountDetailDTO> relationList = JSONObject.parseArray(amountDetail.toJSONString(), InvoiceAmountDetailDTO.class);
        JSONObject amountJSON = new JSONObject();
        //处理子发票
        JSONArray attrList = new JSONArray();
        for (InvoiceAmountDetailDTO relation : relationList) {
            JSONObject attr = new JSONObject();
            //合同
            String contractAttr = PrintInvoiceTotalMoneyEnum.CONTRACT_ID.getAttr();
            List<JSONObject> contract = relation.getContract();
            String contractName = getNamesFromJSONObjectList(contract);
            attr.put(contractAttr, contractName);

            //应收款
            String paymentAttr = PrintInvoiceTotalMoneyEnum.PAYMENT_ID.getAttr();
            List<JSONObject> paymentNo = relation.getPayment();
            String paymentName = getNamesFromJSONObjectList(paymentNo);
            List<JSONObject> paymentSheetNo = relation.getPaymentSheet();
            String paymentSheetName = getNamesFromJSONObjectList(paymentSheetNo);
            //开票金额
            String totalMoneyAttr = PrintInvoiceTotalMoneyEnum.TOTAL_MONEY.getAttr();
            Double invoiceAmount = relation.getInvoiceAmount();
            attr.put(totalMoneyAttr, invoiceAmount);
            if (!StringUtil.isEmpty(paymentName)) {
                attr.put(paymentAttr, paymentName);
            } else if (!StringUtil.isEmpty(paymentSheetName)) {
                attr.put(paymentAttr, paymentSheetName);
            } else {
                attr.put(paymentAttr, "");
            }
            attrList.add(attr);
        }
        amountJSON.put(PrintConstant.ATTRLIST, attrList);
        String amountAttr = PrintSpecialAttrEnum.INVOICE_TOTAL_MONEY_DETAIL.getAttr();
        newData.put(amountAttr, amountJSON);
    }

    /**
     * 处理进项发票明细
     *
     * @param newData 发票数据
     * @param amountDetail 发票明细数据
     * @author 徐俊杰
     * @date 2020/3/23 9:01
     * @since v1.0
     */
    private void disposeInvoicePurchaseTotalMoney(JSONObject newData, JSONArray amountDetail) {
        //todo 这里的RelationshipGetPojo要改成进项发票对应的
        List<InvoiceAmountDetailDTO> relationList = JSONObject.parseArray(amountDetail.toJSONString(), InvoiceAmountDetailDTO.class);
        JSONObject amountJSON = new JSONObject();
        //处理子发票
        JSONArray attrList = new JSONArray();
        for (InvoiceAmountDetailDTO relation : relationList) {
            JSONObject attr = new JSONObject();
            //采购合同
            String purchaseAttr = PrintInvoicePurchaseTotalMoneyEnum.PURCHASE.getAttr();
            List<JSONObject> purchase = relation.getPurchase();
            String purchaseName = getNamesFromJSONObjectList(purchase);
            attr.put(purchaseAttr, purchaseName);
            //付款计划
            String payPlanAttr = PrintInvoicePurchaseTotalMoneyEnum.PAY_PLAN.getAttr();
            List<JSONObject> payPlanNo = relation.getPayPlan();
            String payPlanName = getNamesFromJSONObjectList(payPlanNo);
            List<JSONObject> paySheetNo = relation.getPaySheet();
            String paySheetName = getNamesFromJSONObjectList(paySheetNo);
            //开票金额
            String totalMoneyAttr = PrintInvoicePurchaseTotalMoneyEnum.TOTAL_MONEY.getAttr();
            Double invoiceAmount = relation.getInvoiceAmount();
            attr.put(totalMoneyAttr, invoiceAmount);
            if (!StringUtil.isEmpty(payPlanName)) {
                attr.put(payPlanAttr, payPlanName);
            } else if (!StringUtil.isEmpty(paySheetName)) {
                attr.put(payPlanAttr, paySheetName);
            } else {
                attr.put(payPlanAttr, "");
            }
            attrList.add(attr);
        }
        amountJSON.put(PrintConstant.ATTRLIST, attrList);
        String amountAttr = PrintSpecialAttrEnum.INVOICE_PURCHASE_TOTAL_MONEY_DETAIL.getAttr();
        newData.put(amountAttr, amountJSON);
    }

    /**
     * 从JSONObject列表中获取name并拼凑成names（用,分隔）
     *
     * @param objects JSONObject列表
     * @return java.lang.String
     * @author 徐俊杰
     * @date 2020/3/23 11:05
     * @since v1.0
     */
    private String getNamesFromJSONObjectList(List<JSONObject> objects) {
        if (objects == null) {
            return "";
        }
        StringBuilder names = new StringBuilder();
        for (int i = 0; i < objects.size(); i++) {
            if (i != 0) {
                names.append(",");
            }
            JSONObject object = objects.get(i);
            String name = object.getString("name");
            names.append(name);
        }
        return names.toString();
    }

    /**
     * 获取字段attr信息
     *
     * @param fieldAttrEntities 字段解释
     * @param attrInfo 多行文本信息
     * @return
     *
     * @author: hongxiao
     * @date: 2020-03-07 15:02:29
     * @since: v4.13.0
     * @version: v4.13.0
     */
    private void getAttrInfo(List<FieldAttrEntity> fieldAttrEntities, JSONObject attrInfo) {
        List<String> textareaList = new ArrayList<>();
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            String attr = fieldAttrEntity.getAttr();
            Integer fieldType = fieldAttrEntity.getFieldType();
            // 多行文本
            if (Objects.equals(FieldTypeEnum.TEXTAREA.getType(), fieldType)) {
                textareaList.add(attr);
            }
        }
        if (!textareaList.isEmpty()) {
            attrInfo.put(FieldTypeEnum.TEXTAREA.getAlias(), textareaList);
        }
    }

    /**
     * 获取审批的业务数据
     *
     * @param loginUser
     * @param paasPrintGetDataByProcessDTO
     * @param paasFormEntity
     * @return
     * @throws XbbException
     * @author: hongxiao
     * @date: 2020-02-11 18:14
     * @since: v4.13.0
     * @version: v4.13.0
     */
    public JSONArray getValueByProcess(UserVO loginUser ,PaasPrintGetDataByProcessDTO paasPrintGetDataByProcessDTO, PaasFormEntity paasFormEntity) throws XbbException {
        boolean isUseProcessRecords = enableProcessRecords(paasPrintGetDataByProcessDTO.getCorpid());
        List<FieldAttrEntity> explainEntityList = getExplainList(paasPrintGetDataByProcessDTO.getCorpid(), paasFormEntity.getId(), paasPrintGetDataByProcessDTO.getBusinessType());
        JSONArray valueArray = new JSONArray();
        return getProcessData(loginUser, paasPrintGetDataByProcessDTO, paasFormEntity, isUseProcessRecords, valueArray, explainEntityList);
    }

    /**
     * 批量获取审批的业务数据
     *
     * @param paasPrintGetDatasByProcessDTO
     * @return
     * @throws XbbException
     * @author: hongxiao
     * @date: 2020-02-11 18:15
     * @since: v4.13.0
     * @version: v4.13.0
     */
    public JSONArray getValuesByProcess(UserVO loginUser ,PaasPrintGetDatasByProcessDTO paasPrintGetDatasByProcessDTO, PaasFormEntity paasFormEntity) throws XbbException {
        // 获取是否启用打印审批记录
        boolean isUseProcessRecords = enableProcessRecords(paasPrintGetDatasByProcessDTO.getCorpid());
        List<ProcessTaskIdPojo> taskIdAndNodeIdList = paasPrintGetDatasByProcessDTO.getTaskIdAndNodeIdList();
        JSONArray valueArray = new JSONArray();
        List<FieldAttrEntity> explainEntityList = getExplainList(paasPrintGetDatasByProcessDTO.getCorpid(), paasFormEntity.getId(), paasPrintGetDatasByProcessDTO.getBusinessType());
        for (ProcessTaskIdPojo pojo : taskIdAndNodeIdList ) {

            PaasPrintGetDataByProcessDTO paasPrintGetDataByProcessDTO = new PaasPrintGetDataByProcessDTO(pojo.getProcessTaskId(), pojo.getProcessNodeTaskId());
            BeanUtil.copyProperties(paasPrintGetDatasByProcessDTO, paasPrintGetDataByProcessDTO);
            getProcessData(loginUser, paasPrintGetDataByProcessDTO, paasFormEntity, isUseProcessRecords, valueArray, explainEntityList);
        }

        return valueArray;
    }

    /***
     * 获取表单解释
     *
     * @param corpid
     * @param formId
     * @param businessType
     * @throws
     * @return List<FieldAttrEntity>
     * @author hongxiao
     * @date 2022-11-17 15:41
     * @since
     * @version
     */
    private List<FieldAttrEntity> getExplainList(String corpid, Long formId, Integer businessType) throws XbbException {
        List<FieldAttrEntity> explainList;
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
            WorkOrderExplainEntityExt explainEntityExt = workOrderExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(explainEntityExt)) {
                throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012, ApprovalErrorCodeEnum.API_ERROR_209012.getMsg());
            }
            explainList  = JsonHelperUtil.parseArray(explainEntityExt.getExplains(),FieldAttrEntity.class);
        } else {
            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
            if (Objects.isNull(paasFormExplainEntity)) {
                throw new XbbException(ApprovalErrorCodeEnum.API_ERROR_209012, ApprovalErrorCodeEnum.API_ERROR_209012.getMsg());
            }
            explainList  = JsonHelperUtil.parseArray(paasFormExplainEntity.getExplains(),FieldAttrEntity.class);
        }
        return explainList;
    }

    /**
     * 获取是否启动打印审批记录
     *
     * @param corpid
     * @return
     * @throws
     * @author: hongxiao
     * @date: 2020-02-13 10:49
     * @since: v4.13.0
     * @version: v4.13.0
     */
    private boolean enableProcessRecords(String corpid) {
        // 获取是否启用打印审批记录
        String printProcessRecordsValue = CompanyConfigEnum.PRINT_PROCESS_RECORDS.getValue();
        CompanyConfigEntity companyConfigEntity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.PRINT_PROCESS_RECORDS.getAlias(), corpid);
        if (Objects.nonNull(companyConfigEntity)) {
            printProcessRecordsValue = companyConfigEntity.getConfigValue();
        }
        boolean isUseProcessRecords = Objects.equals(BasicConstant.ONE.toString(), printProcessRecordsValue);
        return isUseProcessRecords;
    }

    /**
     * 获取打印时，审批数据
     *
     * @param loginUser
     * @param paasPrintGetDataByProcessDTO
     * @param paasFormEntity
     * @param isUseProcessRecords
     * @param valueArray
     * @return
     * @throws XbbException
     * @author: hongxiao
     * @date: 2020-02-13 10:50
     * @since: v4.13.0
     * @version: v4.13.0
     */
    private JSONArray getProcessData(UserVO loginUser ,PaasPrintGetDataByProcessDTO paasPrintGetDataByProcessDTO, PaasFormEntity paasFormEntity, boolean isUseProcessRecords, JSONArray valueArray, List<FieldAttrEntity> explainEntityList) throws XbbException {

        ProcessNodeTaskGetDTO processNodeTaskGetDTO = new ProcessNodeTaskGetDTO();
        BeanUtil.copyProperties(paasPrintGetDataByProcessDTO, processNodeTaskGetDTO);

        JSONObject processRecordsObj;
        // 审批详情
        ProcessNodeTaskGetVO processNodeTaskGetVO;

        Integer isWorkflow = paasPrintGetDataByProcessDTO.getIsWorkflow();
        if (Objects.isNull(isWorkflow)) {
            if (commonHelp.isOpenWorkFlow(paasPrintGetDataByProcessDTO.getCorpid())) {
                // 获取审批记录
                processRecordsObj = getWorkflowRecords(processNodeTaskGetDTO, isUseProcessRecords);
                // 工作流
                processNodeTaskGetVO = getWorkflowDetail(processNodeTaskGetDTO);
            } else {
                // 获取审批记录
                processRecordsObj = getProcessRecords(processNodeTaskGetDTO, isUseProcessRecords);
                // 老审批
                processNodeTaskGetVO = getProcessDetail(processNodeTaskGetDTO);
            }
        } else {
            if (Objects.equals(isWorkflow, BasicConstant.ONE)) {
                // 获取审批记录
                processRecordsObj = getWorkflowRecords(processNodeTaskGetDTO, isUseProcessRecords);
                // 工作流
                processNodeTaskGetVO = getWorkflowDetail(processNodeTaskGetDTO);
            } else {
                // 获取审批记录
                processRecordsObj = getProcessRecords(processNodeTaskGetDTO, isUseProcessRecords);
                // 老审批
                processNodeTaskGetVO = getProcessDetail(processNodeTaskGetDTO);
            }
        }

        if (Objects.nonNull(processRecordsObj)) {
            // 审批记录添加登录人
            processRecordsObj.put("loginUser", loginUser);
        }
        // 如果是工单,要获取工单进展和工单动态
        getWorkOrderData(paasPrintGetDataByProcessDTO,processNodeTaskGetVO);

        PrintGetDataVO printGetDataVO = new PrintGetDataVO();
        // 获取业务数据
        JSONObject data = processNodeTaskGetVO.getData();
        if(data == null){
            // 表单数据不存在，直接返回
            valueArray.add(printGetDataVO);
            return valueArray;
        }

        Long entityId = processNodeTaskGetVO.getDataId();
        FormDataGetDTO formDataGetDTO = new FormDataGetDTO();
        BeanUtil.copyProperties(paasPrintGetDataByProcessDTO, formDataGetDTO);
        formDataGetDTO.setDataId(entityId);

        return getEntityDatasByProcess(paasFormEntity, loginUser, explainEntityList, formDataGetDTO.getBusinessType() ,formDataGetDTO, entityId, valueArray, printGetDataVO, processNodeTaskGetVO, processRecordsObj);
    }

    private void getWorkOrderData(PaasPrintGetDataByProcessDTO paasPrintGetDataByProcessDTO ,ProcessNodeTaskGetVO processNodeTaskGetVO )throws  XbbException {
        Locale locale = LocaleContextHolder.getLocale();
        String lang = locale.toString();
        Long dataId = processNodeTaskGetVO.getDataId();
        FormDataGetDTO formDataGetDTO = new FormDataGetDTO();
        BeanUtil.copyProperties(paasPrintGetDataByProcessDTO,formDataGetDTO);
        formDataGetDTO.setDataId(dataId);
        if (Objects.equals(paasPrintGetDataByProcessDTO.getBusinessType(),XbbRefTypeEnum.WORK_ORDER.getCode()) && dataId!=0){
            try {
                String printDynamicData = formFeignClient.getPrintDynamicData(formDataGetDTO,lang);
                String printRelationData = formFeignClient.getPrintRelationData(formDataGetDTO,lang);
                dealProcessWorkOrder(processNodeTaskGetVO, printRelationData);
                dealProcessWorkOrder(processNodeTaskGetVO, printDynamicData);
            } catch (XbbException e) {
                throw e;
            } catch (Exception e){
                LOG.info("获取工单数据出错");
                throw  new XbbException(SystemErrorCodeEnum.API_ERROR_100001,SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }
    }

    private void dealProcessWorkOrder(ProcessNodeTaskGetVO processNodeTaskGetVO, String printDynamicData) throws XbbException {
        JSONObject resultObj = JsonHelperUtil.parseObject(printDynamicData);
        if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
            throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
        }
        JSONObject jsonObject = JsonHelperUtil.parseObject(resultObj.getString("result"), JSONObject.class);
        processNodeTaskGetVO.getData().putAll(jsonObject);
    }

    /**
     * 获取审批详情数据
     *
     * @param processNodeTaskGetDTO
     * @return
     * @throws XbbException
     * @author: hongxiao
     * @date: 2020-02-13 11:23
     * @since: v4.13.0
     * @version: v4.13.0
     */
    private ProcessNodeTaskGetVO getProcessDetail(ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        String dataResult;
        try {
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            dataResult = formFeignClient.getFormDataByProcess(processNodeTaskGetDTO, lang);
        } catch (Exception e) {
            LOG.error("获取流程审批数据报错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, PROCESS_DATA_NOT_EXIST);
        }

        JSONObject resultObj = JsonHelperUtil.parseObject(dataResult);
        if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
            throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
        }
        return JsonHelperUtil.parseObject(resultObj.getString("result"),ProcessNodeTaskGetVO.class);
    }


    /**
     * Description: 获取工作流详情页数据
     * @param processNodeTaskGetDTO
     * @return com.xbongbong.paas.pojo.vo.ProcessNodeTaskGetVO
     * @throws
     * @author 魏荣杰
     * @date 2021/7/7 10:22
     * @since
     */
    private ProcessNodeTaskGetVO getWorkflowDetail(ProcessNodeTaskGetDTO processNodeTaskGetDTO) throws XbbException {
        String dataResult;
        try {
            Locale locale = LocaleContextHolder.getLocale();
            String lang = locale.toString();
            dataResult = formFeignClient.getFormDataForWorkflow(processNodeTaskGetDTO, lang);
        } catch (Exception e) {
            LOG.error("获取工作流详情页数据", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, PROCESS_DATA_NOT_EXIST);
        }

        JSONObject resultObj = JsonHelperUtil.parseObject(dataResult);
        if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)resultObj.get(StringConstant.CODE)) {
            throw new XbbException(resultObj.getIntValue(StringConstant.CODE),resultObj.getString(StringConstant.KEY_ERROR_MSG));
        }
        return JsonHelperUtil.parseObject(resultObj.getString("result"),ProcessNodeTaskGetVO.class);
    }


    /**
     * 获取审批记录
     *
     * @param processNodeTaskGetDTO
     * @param isUseProcessRecords
     * @return
     * @throws XbbException
     * @author: hongxiao
     * @date: 2020-02-13 11:26
     * @since: v4.13.0
     * @version: v4.13.0
     */
    private JSONObject getProcessRecords(ProcessNodeTaskGetDTO processNodeTaskGetDTO, boolean isUseProcessRecords) throws XbbException {
        // 获取审批记录
        if (isUseProcessRecords) {
            String recordsResult;
            try {
                Locale locale = LocaleContextHolder.getLocale();
                String lang = locale.toString();
                recordsResult = formFeignClient.getProcessRecords(processNodeTaskGetDTO, lang);
            } catch (Exception e) {
                LOG.error("获取流程审批记录数据报错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_RECORDS_NOT_EXIST);
            }
            JSONObject recordsObj = JsonHelperUtil.parseObject(recordsResult);
            if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)recordsObj.get(StringConstant.CODE)) {
                throw new XbbException(recordsObj.getIntValue(StringConstant.CODE),recordsObj.getString(StringConstant.KEY_ERROR_MSG));
            }

            return JsonHelperUtil.parseObject(recordsObj.getString("result"));
        }
        return null;
    }

    private JSONObject getWorkflowRecords(ProcessNodeTaskGetDTO processNodeTaskGetDTO, boolean isUseProcessRecords) throws XbbException {
        // 获取审批记录
        if (isUseProcessRecords) {
            String recordsResult;
            try {
                Locale locale = LocaleContextHolder.getLocale();
                String lang = locale.toString();
                recordsResult = formFeignClient.getWorkflowRecords(processNodeTaskGetDTO, lang);
            } catch (Exception e) {
                LOG.error("获取流程审批记录数据报错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PROCESS_RECORDS_NOT_EXIST);
            }
            JSONObject recordsObj = JsonHelperUtil.parseObject(recordsResult);
            if (ErrorCodeEnum.API_SUCCESS.getCode() != (int)recordsObj.get(StringConstant.CODE)) {
                throw new XbbException(recordsObj.getIntValue(StringConstant.CODE),recordsObj.getString(StringConstant.KEY_ERROR_MSG));
            }

            return JsonHelperUtil.parseObject(recordsObj.getString("result"));
        }
        return null;
    }

    /**
     * 获取审批的业务数据
     *
     * @param paasFormEntity
     * @param loginUser
     * @param businessType
     * @param formDataGetDTO
     * @param entityId
     * @param valueArray
     * @param printGetDataVO
     * @return
     * @throws XbbException
     * @author: hongxiao
     * @date: 2020-02-11 18:16
     * @since: v4.13.0
     * @version: v4.13.0
     */
    private JSONArray getEntityDatasByProcess(PaasFormEntity paasFormEntity, UserVO loginUser, List<FieldAttrEntity> explainEntityList, Integer businessType, FormDataGetDTO formDataGetDTO,Long entityId, JSONArray valueArray, PrintGetDataVO printGetDataVO, ProcessNodeTaskGetVO processNodeTaskGetVO, JSONObject processRecordsObj) throws XbbException {

        String corpid = formDataGetDTO.getCorpid();
        PrintTemplateTypeEnum printTemplateTypeEnum = PrintTemplateTypeEnum.getByCode(businessType);

        FormDataGetVO formDataGetVO = new FormDataGetVO();
        BeanUtil.copyProperties(processNodeTaskGetVO, formDataGetVO);
        JSONObject data = formDataGetVO.getData();
        // 处理工单负责人
        if (PrintTemplateTypeEnum.WORKORDER == printTemplateTypeEnum && data.containsKey(WorkOrderEnum.MANAGER_ID.getAttr())) {
            JSONArray managerList = new JSONArray();
            JSONObject managerObj = JsonHelperUtil.parseObject(data.getString(WorkOrderEnum.MANAGER_ID.getAttr()));
            if (!managerObj.isEmpty()) {
                managerList.add(managerObj);
            }
            data.put(WorkOrderEnum.OWNER_ID.getAttr(), managerList);
        }


        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FieldAttrEntity attrEntity : explainEntityList) {
            explainMap.put(attrEntity.getAttr(), attrEntity);
        }

        // 要返回的新data数据
        JSONObject newData = new JSONObject();
        newData.putAll(data);

        if (Objects.equals(businessType, 0)) {
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            BeanUtil.copyProperties(formDataGetDTO, handlerExplainDTO);
            // 创建人
            if (data.get(FieldTypeEnum.CREATORID.getAlias()) instanceof String) {
                // 如果data里有创建人，但是字段解释中没有，会出现这种情况
                handlerExplainDTO.setCreatorId(data.getString(FieldTypeEnum.CREATORID.getAlias()));
            } else {
                JSONObject creator = FastJsonHelper.getJsonObjectOrDefault(data, FieldTypeEnum.CREATORID.getAlias(), null);
                if (Objects.nonNull(creator) && creator.containsKey("id")) {
                    handlerExplainDTO.setCreatorId(creator.getString("id"));
                }
            }
            // 负责人
            List<String> ownerIdList = new ArrayList<>();
            JSONArray ownerList = FastJsonHelper.getJsonArrayOrDefault(data, FieldTypeEnum.OWNERID.getAlias(), null);
            if (Objects.nonNull(ownerList) && !ownerList.isEmpty()) {
                for (Object object: ownerList) {
                    JSONObject jsonObject = (JSONObject) object;
                    ownerIdList.add(jsonObject.getString("id"));
                }
            }
            handlerExplainDTO.setOwnerId(ownerIdList);

            handlerExplainDTO.setExplainList(new ArrayList<>(explainMap.values()));
            handlerExplainDTO.setPaasFormEntityExt((PaasFormEntityExt) paasFormEntity);
            for (String attr : data.keySet()) {
                if (explainMap.containsKey(attr) && Objects.nonNull(explainMap.get(attr))) {
                    FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                    if (!ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())
                            && ExplainUtil.invisibleOfScope(fieldAttrEntity, handlerExplainDTO)) {
                        newData.remove(attr);
                    } else if (ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                        // 子表单相关数据
                        Map<String, FieldAttrEntity> subFieldMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainMap.get(attr).getSubForm().getItems()), null);
                        JSONArray jsonArray = newData.getJSONArray(attr);
                        if (Objects.nonNull(jsonArray)) {
                            for (int i = 0; i < jsonArray.size(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                if (Objects.nonNull(jsonObject)) {
                                    for(String subAttr: jsonObject.keySet()) {
                                        FieldAttrEntity subField = subFieldMap.get(subAttr);
                                        if (Objects.nonNull(subField) && ExplainUtil.invisibleOfScope(subField, handlerExplainDTO)) {
                                            jsonObject.put(subAttr, "******");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // 字段类型：(多行文本字段列表)
        JSONObject attrInfo = new JSONObject();
        getAttrInfo(explainEntityList, attrInfo);
        // 调整字段数据值（有些数组要转成String）
        JSONObject dataLinkInfo = new JSONObject();
        adjustAttrValue(formDataGetVO.getHeadList(), newData,explainEntityList,dataLinkInfo, loginUser);
        // 过滤关联数据未选择的值
        filterLinkDataForNoChoose(newData, explainEntityList);
        // 标签处理
        filterLabelData(newData, explainEntityList);
        dealTemplateField(newData,explainEntityList);
        // 制表人和打印日期
        newData.put(AdditionalPrintAttrEnum.TABLE_MAKER.getAttr(),loginUser.getName());
        newData.put(AdditionalPrintAttrEnum.PRINT_DATE_TIME.getAttr(),DateTimeUtil.getDateStringEpochSecond(DateTimeUtil.getInt()));

        // 审批中amountDetail在data中获取，
        JSONArray amountDetail = JsonHelperUtil.parseArray(data.getString("amountDetail"));
        String printFundType;
        switch (printTemplateTypeEnum) {
            case CONTRACT:
                // 客户地址和客户电话
                addCustomerAddressPhone(corpid, data,newData);
                // 联系人电话
                addContactPhone(corpid,data,newData);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ContractEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData,ContractEnum.PRODUCT.getAttr(), XbbRefTypeEnum.CONTRACT.getCode(), explainMap, corpid, loginUser);
                // 部分字段未启用或不可见的处理
                setHideWithAttrByProcess(formDataGetDTO, explainMap, data, newData);
                break;
            case QUOTATION:
                // 客户地址和客户电话
                customerPhoneAddress(corpid, data,newData);
                // 联系人地址和电话
                contactPhoneAddress(corpid,data,newData);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(QuotationEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData,QuotationEnum.PRODUCT.getAttr(), XbbRefTypeEnum.QUOTATION.getCode(), explainMap, corpid, loginUser);
                // 部分字段未启用或不可见的处理
                setHideWithAttrByProcess(formDataGetDTO, explainMap, data, newData);
                break;
            case SALES_OPPORTUNITY:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(SalesOpportunityEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData,SalesOpportunityEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), explainMap, corpid, loginUser);
                // 部分字段未启用或不可见的处理
                setHideWithAttrByProcess(formDataGetDTO, explainMap, data, newData);
                break;
            case WORKREPORT:
                // setHideWithAttr(formDataGetDTO, explainMap, data, newData);
                // setWorkReportStatisticAttr(data,newData, WorkReportDailyEnum.THIS_STATISTIC.getAttr(), workReportDetailVO);
                break;
            case REFUND:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(RefundEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 退货产品
                setTabProductsAttrByProcess(data,newData, RefundEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.REFUND.getCode(), explainMap, corpid, loginUser);
                break;
            case PURCHASE:
                addSupplierData(corpid,data,newData,PurchaseEnum.SUPPLIER_ID.getAttr(),formDataGetDTO);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(PurchaseEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData,PurchaseEnum.PRODUCT.getAttr(), XbbRefTypeEnum.PURCHASE.getCode(), explainMap, corpid, loginUser);
                break;
            case RETURNED_PURCHASE:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ReturnedPurchaseEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, ReturnedPurchaseEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), explainMap, corpid, loginUser);
                // 供应商相关
                addSupplierData(corpid,data,newData, ReturnedPurchaseEnum.SUPPLIER_ID.getAttr(),formDataGetDTO);
                break;
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
            case OTHER_INSTOCK:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(InstockEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, InstockEnum.PRODUCT.getAttr(), XbbRefTypeEnum.INSTOCK.getCode(), explainMap, corpid, loginUser);
                // 23940 【WEB-其他入库单】打印界面“业务类型”为其他入库时，关联单据值回显优化
                if (Objects.equals(businessType, PrintTemplateTypeEnum.OTHER_INSTOCK.getCode())) {
                    String type = newData.getString(InstockEnum.TYPE.getAttr());
                    if (Objects.equals(type, InstockTypeEnum.OTHER_INSTOCK.getName())) {
                        newData.put(InstockEnum.REF_ID.getAttr(), I18nMessageUtil.getMessage(CommonConstant.NOTHING));
                    }
                }
                break;
            case CONTRACT_OUTSTOCK:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(OutstockEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, OutstockEnum.PRODUCT.getAttr(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), explainMap, corpid, loginUser);
                // 部分字段未启用或不可见的处理
                setHideWithAttrByProcess(formDataGetDTO, explainMap, data, newData);
                break;
            case WORK_ORDER_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case OUTSTOCK:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(OutstockEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, OutstockEnum.PRODUCT.getAttr(), XbbRefTypeEnum.OUTSTOCK.getCode(), explainMap, corpid, loginUser);
                break;
            case INVENTORY:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(InventoryEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, InventoryEnum.PRODUCT.getAttr(), XbbRefTypeEnum.INVENTORY.getCode(), explainMap, corpid, loginUser);
                // 部分字段未启用或不可见的处理
                setHideWithAttrByProcess(formDataGetDTO, explainMap, data, newData);
                break;
            case TRANSFER:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(TransferEnum.PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, TransferEnum.PRODUCTS.getAttr(), XbbRefTypeEnum.TRANSFER.getCode(), explainMap, corpid, loginUser);
                setWarehouseManager(corpid,data,newData,TransferEnum.INTO_WAREHOUSE_ID.getAttr(),TransferEnum.OUT_WAREHOUSE_ID.getAttr());
                break;
            case ASSEMBLE:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(AssembleEnum.OUT_PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                proFormHelp.setProductAccuracy(explainMap.get(AssembleEnum.IN_PRODUCTS.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, AssembleEnum.IN_PRODUCTS.getAttr(), XbbRefTypeEnum.ASSEMBLE.getCode(), explainMap, corpid, loginUser);
                setWarehouseManager(corpid,data,newData, AssembleEnum.INTO_WAREHOUSE_ID.getAttr(),AssembleEnum.OUT_WAREHOUSE_ID.getAttr());
                break;
            case BOMBILL:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(BomBillEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                proFormHelp.setProductAccuracy(explainMap.get(BomBillEnum.MATERIEL.getAttr()),corpid, loginUser.getUserId());
                setTabProductsAttrByProcess(data,newData, BomBillEnum.PRODUCT.getAttr(), XbbRefTypeEnum.BOM_BILL.getCode(), explainMap, corpid, loginUser);
                JSONArray ownerList = data.getJSONArray("ownerId");
                if (Objects.nonNull(ownerList) && !ownerList.isEmpty()) {
                    List<UserTeamEntity> userTeamEntityList = new ArrayList<>();
                    for (Object object: ownerList) {
                        JSONObject jsonObject = (JSONObject) object;
                        UserTeamEntity teamEntity = new UserTeamEntity();
                        teamEntity.setUserId(jsonObject.getString("id"));
                        teamEntity.setUserName(jsonObject.getString("name"));
                        userTeamEntityList.add(teamEntity);
                    }
                    StringBuilder managerNameBuilder = new StringBuilder();
                    setManagers(userTeamEntityList, managerNameBuilder);
                    newData.put(AdditionalPrintAttrEnum.MANAGER.getAttr(),managerNameBuilder.toString());
                }
                break;
            case PRODUCTIONORDER:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ProductionOrderEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                proFormHelp.setProductAccuracy(explainMap.get(ProductionOrderEnum.MATERIEL.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, ProductionOrderEnum.PRODUCT.getAttr(), XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), explainMap, corpid, loginUser);
                JSONArray prodOrderOwnerList = data.getJSONArray("ownerId");
                if (Objects.nonNull(prodOrderOwnerList) && !prodOrderOwnerList.isEmpty()) {
                    List<UserTeamEntity> productionOrderUserList = new ArrayList<>();
                    for (Object object: prodOrderOwnerList) {
                        JSONObject jsonObject = (JSONObject) object;
                        UserTeamEntity teamEntity = new UserTeamEntity();
                        teamEntity.setUserId(jsonObject.getString("id"));
                        teamEntity.setUserName(jsonObject.getString("name"));
                        productionOrderUserList.add(teamEntity);
                    }
                    StringBuilder managerBuilder = new StringBuilder();
                    setManagers(productionOrderUserList, managerBuilder);
                    newData.put(AdditionalPrintAttrEnum.MANAGER.getAttr(),managerBuilder.toString());
                }
                break;
            case PAYMENT_SHEET:
                String printFundPaymentTypeJsonStr = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
                JSONObject paymentjsonObject = JSON.parseObject(printFundPaymentTypeJsonStr);
                newData.put("printFundType", paymentjsonObject.get("value"));
                if (CollectionsUtil.isNotEmpty(amountDetail)) {
                    if (amountDetail.size() > BasicConstant.ONE) {
                        disposePaymentSheetAmount(newData, amountDetail);
                    }
                }
                break;
            case PAY_SHEET:
                String printFundTypePayJsonStr = data.getString(PaySheetEnum.PAY_SHEET_TYPE.getAttr());
                JSONObject payjsonObject = JSON.parseObject(printFundTypePayJsonStr);
                newData.put("printFundType", payjsonObject.get("value"));
                if(CollectionsUtil.isNotEmpty(amountDetail)){
                    if (amountDetail.size() > BasicConstant.ONE) {
                        disposePaySheetAmount(newData, amountDetail);
                    }
                }
                break;
            case INVOICE:
                addInvoiceLinkAddress(newData, XbbRefTypeEnum.INVOICE);
                if(CollectionsUtil.isNotEmpty(amountDetail)){
                    disposeInvoiceTotalMoney(newData, amountDetail);
                }
                /*addInvoiceLinkAddress(newData, XbbRefTypeEnum.INVOICE);
                if (Objects.nonNull(amountDetail) && !amountDetail.isEmpty()) {
                    // attr转换成saasAttr
                    JSONArray newAmountDetail = new JSONArray();
                    for (Object obj : amountDetail) {
                        JSONObject jsonObject = JsonHelperUtil.parseObject(obj.toString());
                        if (jsonObject.isEmpty()) {
                            continue;
                        }

                        Long contractId = 0L;
                        String contractNo = "";
                        Long paymentId = 0L;
                        String paymentNo = "";
                        Double contractInvoiceAmount = 0D;
                        Double paymentInvoiceAmount = 0D;

                        for (String key : jsonObject.keySet()) {
                            String saasAttr = InvoiceEnum.getSaasAttrByAttr(key);
                            if (Objects.isNull(saasAttr)) {
                                continue;
                            }
                            if (Objects.equals(InvoiceEnum.CONTRACT_ID.getAttr(), key)) {
                                JSONArray contractIdArr = jsonObject.getJSONArray(key);
                                if (!contractIdArr.isEmpty()) {
                                    JSONObject contractIdObj = contractIdArr.getJSONObject(0);
                                    contractId = contractIdObj.getLong("id");
                                    contractNo = contractIdObj.getString("name");
                                }

                            } else if (Objects.equals(InvoiceEnum.TOTAL_MONEY.getAttr(), key)) {
                                contractInvoiceAmount = jsonObject.getDouble(key);
                                paymentInvoiceAmount = jsonObject.getDouble(key);
                            } else if (Objects.equals(InvoiceEnum.PAYMENT_ID.getAttr(), key)) {
                                JSONArray paymentIdArr = jsonObject.getJSONArray(key);
                                if (!paymentIdArr.isEmpty()) {
                                    JSONObject contractIdObj = paymentIdArr.getJSONObject(0);
                                    paymentId = contractIdObj.getLong("id");
                                    paymentNo = contractIdObj.getString("name");
                                }
                            }
                        }
                        RelationshipGetPojo pojo = new RelationshipGetPojo();
                        pojo.setContractId(contractId);
                        pojo.setContractNo(contractNo);
                        pojo.setContractInvoiceAmount(contractInvoiceAmount);
                        pojo.setPaymentId(paymentId);
                        pojo.setPaymentNo(paymentNo);
                        pojo.setPaymentInvoiceAmount(paymentInvoiceAmount);
                        newAmountDetail.add(pojo);
                    }
                    disposeInvoiceTotalMoney(newData, newAmountDetail);
                }*/
                break;
            case INVOICE_PURCHASE:
                addInvoiceLinkAddress(newData, XbbRefTypeEnum.PURCHASE_INVOICE);
                if(CollectionsUtil.isNotEmpty(amountDetail)){
                    disposeInvoicePurchaseTotalMoney(newData, amountDetail);
                }
                break;
            case WORKORDER:
                // 客户地址和客户电话
                workOrderPhoneAddress(corpid, data,newData);
                // 联系人
                workOrderContact(corpid,data,newData);
                // 关联产品
                formDataGetDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                // 关联产品
                setTabProductsAttrByProcess(data,newData,WorkOrderEnum.SPARE_PARTS.getAttr(), XbbRefTypeEnum.CONTRACT.getCode(), explainMap, corpid, loginUser);
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(WorkOrderEnum.SPARE_PARTS.getAttr()),corpid, loginUser.getUserId());

                // 部分字段未启用或不可见的处理
                setHideWithAttrByProcess(formDataGetDTO, explainMap, data, newData);
                break;
            case COST_ADJUST:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(CostAdjustEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, CostAdjustEnum.PRODUCT.getAttr(), XbbRefTypeEnum.COST_ADJUST.getCode(), explainMap, corpid, loginUser);
                break;
            case RECEIPT_ORDER:
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ReceiptOrderEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, ReceiptOrderEnum.PRODUCT.getAttr(), XbbRefTypeEnum.RECEIPT_ORDER.getCode(), explainMap, corpid, loginUser);
                setTabServiceAttrByProcess(data,newData, ReceiptOrderEnum.SERVICE_PROJECT.getAttr(), XbbRefTypeEnum.RECEIPT_ORDER.getCode(), explainMap, corpid, loginUser);
                break;
            case WORK_ORDER_V2:
                // 同步关联产品字段设置
                //proFormHelp.setProductAccuracy(explainMap.get(WorkOrderV2Enum.PRODUCT.getAttr()),corpid, userEntity.getUserId());
                //处理特殊字段回显示
                // 同步关联产品字段设置
                proFormHelp.setProductAccuracy(explainMap.get(ReceiptOrderEnum.PRODUCT.getAttr()),corpid, loginUser.getUserId());
                // 关联产品
                setTabProductsAttrByProcess(data,newData, ReceiptOrderEnum.PRODUCT.getAttr(), XbbRefTypeEnum.WORK_ORDER_V2.getCode(), explainMap, corpid, loginUser);
                fixWorkOrderV2data(corpid, data,newData);
                break;
            default:
                break;
        }
        // 审批状态和总耗时
        JSONObject processDetail = new JSONObject();
        processDetail.put("flowStatus", processNodeTaskGetVO.getFlowStatus());
        processDetail.put("processTime", processNodeTaskGetVO.getProcessTime());

        printGetDataVO.setProcessDetail(processDetail);
        printGetDataVO.setData(newData);
        printGetDataVO.setDataLinkInfo(dataLinkInfo);
        printGetDataVO.setAttrInfo(attrInfo);
        if (Objects.nonNull(processRecordsObj)) {
            printGetDataVO.setProcessRecords(processRecordsObj);
        }
        valueArray.add(printGetDataVO);
        return valueArray;
    }

    private void fixWorkOrderV2data(String corpid, JSONObject data, JSONObject newData) throws XbbException{
        WorkOrderV2FixDataDTO workOrderV2FixDataDTO=new WorkOrderV2FixDataDTO();
        workOrderV2FixDataDTO.setData(data);
        workOrderV2FixDataDTO.setCorpid(corpid);
        XbbResponse<WorkOrderV2FixDataVO> xbbResponse = workOrderV2FixDataFeignClient.fixData(workOrderV2FixDataDTO);
        if (!xbbResponse.isSuccess()) {
            throw new XbbException(xbbResponse.getCode(), xbbResponse.getMsg());
        }
        WorkOrderV2FixDataVO result= xbbResponse.getResult();
        //因为缺乏新工单枚举，先写死
        newData.put("text_5",result.getData().get("text_5"));
        newData.put("text_7",result.getData().get("text_7"));
    }

    /**
     * 处理审批打印字段权限
     *
     * @param formDataGetDTO　入参
     * @param explainMap　解释
     * @param data
     * @param newData 新数据
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-03-31 16:58
     * @since v4.16.0
     * @version v4.16.0
     */
    private void setHideWithAttrByProcess(FormDataGetDTO formDataGetDTO, Map<String, FieldAttrEntity> explainMap, JSONObject data, JSONObject newData) {

        for (String attr : data.keySet()) {
            if (explainMap.containsKey(attr) && Objects.nonNull(explainMap.get(attr))) {
                FieldAttrEntity fieldAttrEntity = explainMap.get(attr);
                if (!ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                    if (Objects.equals(BasicConstant.ONE, fieldAttrEntity.getVisible())) {
                        continue;
                    }
                    newData.put(attr, StringConstant.INVISIBLE_VALUE);
                } else if (ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                    // 子表单相关数据
                    Map<String, FieldAttrEntity> subFieldMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainMap.get(attr).getSubForm().getItems()), null);
                    // attrList 取自 adjustAttrValue()方法
                    FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());
                    // 工作报告今日计划不走权限
                    if (Objects.equals(PrintTemplateTypeEnum.WORKREPORT.getCode(), formDataGetDTO.getBusinessType()) && (fieldTypeEnum != null  && fieldTypeEnum.equals(FieldTypeEnum.SWITCH_TEXT))) {
                        continue;
                    }
                    // // 联系方式(工单特殊处理)(其他的我也不知道存在这样的情况)
                    if ((Objects.equals(ContractOutstockEnum.CUSTOMER_PHONE.getAttr(),attr) && Objects.equals(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(),formDataGetDTO.getBusinessType())) ||(Objects.equals(WorkOrderEnum.CONTACT_INFORMATION.getAttr(),attr) && Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(),formDataGetDTO.getBusinessType()))){
                        FieldAttrEntity fieldAttr = explainMap.get(attr);
                        if(Objects.nonNull(fieldAttr) && Objects.equals(BasicConstant.ZERO, explainMap.get(attr).getVisible())) {
                            newData.put(attr, StringConstant.INVISIBLE_VALUE);
                        }
                        continue;
                    }
                    if (Objects.equals(WorkOrderEnum.SPARE_PARTS.getAttr(),attr) && Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(),formDataGetDTO.getBusinessType())){
                        FieldAttrEntity fieldAttr = explainMap.get(attr);
                        if(Objects.nonNull(fieldAttr) && Objects.equals(BasicConstant.ZERO, explainMap.get(attr).getVisible())) {
                            newData.put(attr, StringConstant.INVISIBLE_VALUE);
                        }
                        continue;
                    }
                    JSONArray jsonArray;
                    try {
                        JSONObject attrObj = FastJsonHelper.getJsonObjectFromFormData(newData, attr);
                        jsonArray = FastJsonHelper.getJsonArrFromFormData(attrObj, PrintConstant.ATTRLIST);
                    } catch (XbbException e) {
                        jsonArray = null;
                    }
                    if (Objects.isNull(jsonArray)) {
                        continue;
                    }
                    for (Object obj : jsonArray) {
                        JSONObject jsonObject = (JSONObject) obj;
                        if (Objects.isNull(jsonObject)) {
                            continue;
                        }
                        for(String subAttr: jsonObject.keySet()) {
                            FieldAttrEntity subField = subFieldMap.get(subAttr);
                            if(Objects.nonNull(subField) && Objects.equals(BasicConstant.ZERO, subField.getVisible())) {
                                jsonObject.put(subAttr, StringConstant.INVISIBLE_VALUE);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 通过审批获取关联的产品数据
     *
     * @param data
     * @param newData
     * @param productAttr
     * @param xbbRefType
     * @return
     * @throws
     * @author: hongxiao
     * @date: 2020-02-13 18:01
     * @since: v4.13.0
     * @version: 4.13.0
     */
    private void setTabProductsAttrByProcess(JSONObject data, JSONObject newData, String productAttr, Integer xbbRefType, Map<String, FieldAttrEntity> explainMap, String corpid, UserVO loginUser) throws XbbException {
        JSONArray productArray = data.getJSONArray(productAttr);
        if (Objects.equals(XbbRefTypeEnum.ASSEMBLE.getCode(),xbbRefType)) {
            // 装配出入库单产品
            // TODO 产品解析
            JSONArray instockProductArray = data.getJSONArray(AssembleEnum.IN_PRODUCTS.getAttr());
            JSONArray outstockProductArray = data.getJSONArray(AssembleEnum.OUT_PRODUCTS.getAttr());

            JSONObject instockNewProduct = adjustAttrValueByProcess(instockProductArray, explainMap.get(AssembleEnum.IN_PRODUCTS.getAttr()), ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr());
            JSONObject outstockNewProduct = adjustAttrValueByProcess(outstockProductArray, explainMap.get(AssembleEnum.OUT_PRODUCTS.getAttr()), ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr());
            if (Objects.nonNull(instockNewProduct)) {
                newData.put(AssembleEnum.IN_PRODUCTS.getAttr(),instockNewProduct);
            }
            if (Objects.nonNull(outstockNewProduct)) {
                newData.put(AssembleEnum.OUT_PRODUCTS.getAttr(), outstockNewProduct);
            }
            return;
        } else if (Objects.equals(XbbRefTypeEnum.BOM_BILL.getCode(),xbbRefType)) {
            // bom清单和生产出入库单 产品
            JSONArray finishedProductArray = data.getJSONArray(BomBillEnum.PRODUCT.getAttr());
            JSONArray materielArray = data.getJSONArray(BomBillEnum.MATERIEL.getAttr());

            JSONObject finishedNewProduct = adjustAttrValueByProcess(finishedProductArray, explainMap.get(BomBillEnum.PRODUCT.getAttr()), ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr());
            JSONObject materielNewProduct = adjustAttrValueByProcess(materielArray, explainMap.get(BomBillEnum.MATERIEL.getAttr()), ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr());

            newData.put(BomBillEnum.PRODUCT.getAttr(),finishedNewProduct);
            newData.put(BomBillEnum.MATERIEL.getAttr(),materielNewProduct);
            return;
        } else if (Objects.equals(XbbRefTypeEnum.PRODUCTION_ORDER.getCode(),xbbRefType)) {
            // 生产出入库单 产品
            JSONArray finishedProductArray = data.getJSONArray(ProductionOrderEnum.PRODUCT.getAttr());
            JSONArray materielArray = data.getJSONArray(ProductionOrderEnum.MATERIEL.getAttr());

            JSONObject finishedNewProduct = adjustAttrValueByProcess(finishedProductArray, explainMap.get(ProductionOrderEnum.PRODUCT.getAttr()), ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr());
            JSONObject materielNewProduct = adjustAttrValueByProcess(materielArray, explainMap.get(ProductionOrderEnum.MATERIEL.getAttr()), ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr());

            newData.put(ProductionOrderEnum.PRODUCT.getAttr(),finishedNewProduct);
            newData.put(ProductionOrderEnum.MATERIEL.getAttr(),materielNewProduct);
            return;
        } else if (Objects.equals(xbbRefType, XbbRefTypeEnum.OUTSTOCK.getCode()) ||Objects.equals(xbbRefType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode())) {
            // 把销售出库单单独提出去,这儿做个兼容处理
            for (int i=0; i<productArray.size(); i++) {
                JSONObject productItemObj = productArray.getJSONObject(i);
                if (Objects.equals(productItemObj.getString("attr"), OutstockSaleRelativeConstantEnum.PRICE.getAlias())) {
                    productItemObj.put("attr", RelativeProductEnum.PRODUCT_PRICE.getSaasAttr());
                    break;
                }
            }
        } else if (Objects.equals(xbbRefType, XbbRefTypeEnum.COST_ADJUST.getCode())) {
            for (int i=0; i < productArray.size(); i++) {
                JSONObject productItemObj = productArray.getJSONObject(i);
                JSONObject unitInfo = productItemObj.getJSONObject(CostAdjustProductEnum.BASIC_UNIT.getAttr());
                if (Objects.nonNull(unitInfo)){
                    String unit = unitInfo.getString(StringConstant.TEXT);
                    productItemObj.put(SelectProductEnum.BUSINESS_UNIT.getAttr(), unit);
                }
                Object produceDateObj = productItemObj.get(CostAdjustProductEnum.PRODUCE_DATE.getAttr());
                if (Objects.equals(productItemObj.getInteger(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr()), 1) && Objects.nonNull(produceDateObj) && !Objects.equals(produceDateObj,0)) {
                    Long produceDate = FastJsonHelper.getLongOrDefaultFromFormData(productItemObj, CostAdjustProductEnum.PRODUCE_DATE.getAttr(), 0L);
                    Long guaranteePeriod = FastJsonHelper.getLongOrDefaultFromFormData(productItemObj, CostAdjustProductEnum.GUARANTEE_PERIOD.getAttr(), 0L);
                    Double sub = Arith.add(new Double(produceDate), Arith.mul(86400, guaranteePeriod));
                    productItemObj.put(CostAdjustProductEnum.EXPIRE_DATE.getAttr(), sub.longValue());
                }else {
                    productItemObj.remove(CostAdjustProductEnum.PRODUCE_DATE.getAttr());
                    productItemObj.remove(CostAdjustProductEnum.GUARANTEE_PERIOD.getAttr());
                    productItemObj.remove(CostAdjustProductEnum.EXPIRE_DATE.getAttr());
                }
            }
        }
        // 其他表单的产品处理
        if (productArray == null) {
            return;
        }


        // linkData
        String productNameAttr = "";
        FieldAttrEntity fieldAttrEntity = explainMap.get(productAttr);
        if (Objects.isNull(fieldAttrEntity)) {
            return;
        }
        List<FieldAttrEntity> items = (List<FieldAttrEntity>)fieldAttrEntity.getSubForm().getItems();
        for (FieldAttrEntity attrEntity : items) {
            LinkInfoPojo linkInfoPojo = attrEntity.getLinkInfo();
            if (Objects.equals(BasicConstant.ZERO, attrEntity.getIsRedundant()) && Objects.nonNull(linkInfoPojo) && Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
                productNameAttr = attrEntity.getAttr();
                break;
            }
        }
        JSONObject newProduct = adjustAttrValueByProcess(productArray, explainMap.get(productAttr), productNameAttr);
        if (Objects.equals(xbbRefType, XbbRefTypeEnum.INSTOCK.getCode())){
            //处理产品子表单的可见与不可见
            setProductSubForm(newProduct, data, loginUser, explainMap.get(productAttr));
        }
        JSONArray newProductArray = newProduct.getJSONArray(PrintConstant.ATTRLIST);
        newData.put(productAttr,newProduct);
        // 汇总信息
        List<Integer> outstckTypes = Arrays.asList(XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.OUTSTOCK.getCode(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(), XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
        if (outstckTypes.contains(xbbRefType) || Objects.equals(xbbRefType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.PURCHASE.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.QUOTATION.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.RECEIPT_ORDER.getCode()) || Objects.equals(xbbRefType, XbbRefTypeEnum.WORK_ORDER_V2.getCode())) {
            // 出库数量总计，出库成本总计，产品售价合计
            Double outNumTotal = 0D;
            Double outProductCostTotal = 0D;
            Double priceTotal = 0D;
            for (Object object : newProductArray) {
                JSONObject jsonObject = JsonHelperUtil.parseObject(object.toString());
                for (String key : jsonObject.keySet()) {
                    if (Objects.equals(ProductPrintHelpEnum.NUM.getNewAttr(), key)) {
                        outNumTotal = Arith.add(outNumTotal, jsonObject.getDouble(SelectProductEnum.BUSINESS_NUM.getAttr()));
                    }
                    if (Objects.equals(ProductPrintHelpEnum.TOTAL_COST.getNewAttr(), key)) {
                        outProductCostTotal = Arith.add(outProductCostTotal, jsonObject.getDouble(key));
                    }
                    if (Objects.equals(ProductPrintHelpEnum.SUBTOTAL.getNewAttr(), key)) {
                        priceTotal = Arith.add(priceTotal, jsonObject.getDouble(key));
                    }
                }
            }
            // 精度参数setTabProductsAttr方法中的：dealSaleSpecialAttr、dealQuoTationProductSpecialAttr、dealProductSpecialAttr、dealContractOutstock、dealJxcProductSpecialAttr中的精度
            // 机会：产品单价的精度；合同＆报价单：产品合计的精度；销售出库＆采购合同：产品库存数量的精度
            // 使用表单字段精度，机会：预计金额的精度；合同＆报价单：产品合计的精度；
//            ProductFieldPojo costField = proFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_PRICE,ProductEnum.PRICE.getAttr(), corpid);
            Integer accuracy = BasicConstant.TWO;
            FieldAttrEntity productTotalField;
            JSONObject surcharge = new JSONObject();
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(xbbRefType);
            switch (xbbRefTypeEnum) {
                case CONTRACT:
//                    PaasFormExplainEntity contractExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.CONTRACT.getCode(), corpid);
//                    Map<String, FieldAttrEntity> contractExplainMap = ExplainUtil.getExplainMap(contractExplainEntity.getExplains(),  ContractEnum.PRODUCT_TOTAL.getAttr());
                    productTotalField = explainMap.get(ContractEnum.PRODUCT_TOTAL.getAttr());
                    if (Objects.nonNull(productTotalField)) {
                        accuracy = productTotalField.getAccuracy();
                    }
                    break;
                case QUOTATION:
//                    PaasFormExplainEntity quotationExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.QUOTATION.getCode(), corpid);
//                    Map<String, FieldAttrEntity> quotationExplainMap = ExplainUtil.getExplainMap(quotationExplainEntity.getExplains(), QuotationEnum.PRODUCT_TOTAL.getAttr());
                    productTotalField = explainMap.get(QuotationEnum.PRODUCT_TOTAL.getAttr());
                    if (Objects.nonNull(productTotalField)) {
                        accuracy = productTotalField.getAccuracy();
                    }
                    break;
                case SALES_OPPORTUNITY:
//                    ProductFieldPojo costField = proFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_PRICE,ProductEnum.PRICE.getAttr(), corpid);
//                    accuracy = costField.getAccuracy();
                    productTotalField = explainMap.get(SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr());
                    if (Objects.nonNull(productTotalField)) {
                        accuracy = productTotalField.getAccuracy();
                    }
                    break;
                case CONTRACT_OUTSTOCK:
                case PURCHASE:
                    ProductFieldPojo stockField = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_STOCK, ProductEnum.STOCK.getAttr(), corpid);
                    if (Objects.nonNull(stockField)) {
                        accuracy = stockField.getAccuracy();
                    }
                    break;
                case RECEIPT_ORDER:
                    productTotalField = explainMap.get(ReceiptOrderEnum.PRODUCT_TOTAL.getAttr());
                    if (Objects.nonNull(productTotalField)) {
                        accuracy = productTotalField.getAccuracy();
                    }
                    break;
            }
            // 先算精度
            priceTotal = attrDecimalPrecisionHelper.setPrecision(priceTotal, accuracy);
            switch (xbbRefTypeEnum){
                case CONTRACT:
                case QUOTATION:
                case SALES_OPPORTUNITY:
                case CONTRACT_OUTSTOCK:
                case PURCHASE:
                    getDetailMoney(newProduct, priceTotal, accuracy, surcharge);
                    if (Objects.equals(XbbRefTypeEnum.CONTRACT_OUTSTOCK, xbbRefTypeEnum)){
                        JSONObject sumAttrList = newProduct.getJSONObject("sumAttrList");
                        sumAttrList.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias(), outProductCostTotal);
                        sumAttrList.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_AMOUNT.getAlias(), outNumTotal);
                        sumAttrList.put(OutstockSaleRelativeConstantEnum.SALE_PRICE_AMOUNT.getAlias(), priceTotal);
                    }
                    break;
                case OUTSTOCK:
                case OTHER_OUTSTOCK:
                case RETURNED_PURCHASE_OUTSTOCK:
                case PRODUCTION_MATERIEL_OUTSTOCK:
                case WORK_ORDER_OUTSTOCK:
                    // 出库单产品
                    JSONObject others = new JSONObject();
                    others.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_COST_AMOUNT.getAlias(), outProductCostTotal);
                    others.put(OutstockSaleRelativeConstantEnum.OUTSTOCK_AMOUNT.getAlias(), outNumTotal);
                    others.put(OutstockSaleRelativeConstantEnum.SALE_PRICE_AMOUNT.getAlias(), priceTotal);
                    newProduct.put("sumAttrList",others);
                    break;
                case RECEIPT_ORDER:
                    getDetailMoney(newProduct, priceTotal, accuracy, surcharge);
                    break;
                case WORK_ORDER_V2:
                    getDetailMoney(newProduct, priceTotal, accuracy, surcharge);
                    break;
            }
        }

    }


    /**
     * 通过审批获取关联的服务数据
     *
     * @param data
     * @param newData
     * @param productAttr
     * @param xbbRefType
     * @return
     * @throws
     * @author: hongxiao
     * @date: 2020-02-13 18:01
     * @since: v4.13.0
     * @version: 4.13.0
     */
    private void setTabServiceAttrByProcess(JSONObject data, JSONObject newData, String serviceAttr, Integer xbbRefType, Map<String, FieldAttrEntity> explainMap, String corpid, UserVO loginUser) throws XbbException {
        JSONArray serviceArray = data.getJSONArray(serviceAttr);
        // 其他表单的产品处理
        if (serviceArray == null) {
            return;
        }
        // linkData
        String serviceNameAttr = "";
        FieldAttrEntity fieldAttrEntity = explainMap.get(serviceAttr);
        if (Objects.isNull(fieldAttrEntity)) {
            return;
        }
        List<FieldAttrEntity> items = (List<FieldAttrEntity>)fieldAttrEntity.getSubForm().getItems();
        for (FieldAttrEntity attrEntity : items) {
            LinkInfoPojo linkInfoPojo = attrEntity.getLinkInfo();
            if (Objects.equals(BasicConstant.ZERO, attrEntity.getIsRedundant()) && Objects.nonNull(linkInfoPojo) && Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum.SERVICE_PROJECT.getCode())) {
                serviceNameAttr = attrEntity.getAttr();
                break;
            }
        }
        JSONObject newProduct = serviceAttrValueByProcess(serviceArray, explainMap.get(serviceAttr), serviceNameAttr);
        JSONArray newProductArray = newProduct.getJSONArray(PrintConstant.ATTRLIST);
        // 出库单产品
        Double priceTotal = 0D;
        for (Object object : newProductArray) {
            JSONObject jsonObject = JsonHelperUtil.parseObject(object.toString());
            for (String key : jsonObject.keySet()) {
                if (Objects.equals(ServicePrintHelpEnum.SUBTOTAL.getNewAttr(), key)) {
                    priceTotal = Arith.add(priceTotal, jsonObject.getDouble(key));
                }
            }
        }
        JSONObject surcharge = new JSONObject();
        Integer accuracy = BasicConstant.TWO;
        FieldAttrEntity productTotalField = explainMap.get(ReceiptOrderEnum.SERVICE_TOTAL.getAttr());
        if (Objects.nonNull(productTotalField)) {
            accuracy = productTotalField.getAccuracy();
        }

        getDetailMoney(newProduct, priceTotal, accuracy, surcharge);
        newData.put(serviceAttr,newProduct);


    }

    private void getDetailMoney(JSONObject newProduct, Double priceTotal, Integer accuracy, JSONObject surcharge) {
        String digitUpperMoney = MoneyUtil.doubleToUppercase(priceTotal);
        String amountStr  = digitUpperMoney + " " + AttrDecimalPrecisionHelper.parseThousandth(priceTotal, accuracy);
        String bigMoney = digitUpperMoney;
        String smallMoney = AttrDecimalPrecisionHelper.parseThousandth(priceTotal, accuracy).toString();
        surcharge.put(BusinessConstant.TOTAL_PRODUCT_MONEY, amountStr);
        surcharge.put(BusinessConstant.DIGIT_UPPER_MONEY, bigMoney);
        surcharge.put(BusinessConstant.SMALL_MONEY, smallMoney);
        newProduct.put("sumAttrList",surcharge);
    }

    /**
     * 关联产品名称处理
     *
     * @param productArray 产品列表
     * @param productNameAttr 产品名称attr
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-04-01 15:26
     * @since v4.16.0
     * @version v4.16.0
     */
    private JSONArray handleProductName(JSONArray productArray, String productNameAttr, List<LinkedAttrPoJo> linkshowAttrList) {
        JSONArray newProductArray = new JSONArray();
        if (Objects.isNull(linkshowAttrList) || linkshowAttrList.isEmpty()) {
            return productArray;
        }
        List<String> showAttrList = new ArrayList<>();
        for (LinkedAttrPoJo poJo : linkshowAttrList) {
            showAttrList.add(poJo.getAttr());
        }
        for (int i=0; i<productArray.size(); i++) {
            JSONObject productItemObj = productArray.getJSONObject(i);
            JSONObject oldData = new JSONObject();
            for (String key : productItemObj.keySet()) {
                // 产品名称字段处理
                if (Objects.equals(key, productNameAttr)) {
                    String name = "";
                    JSONObject productNameDataObj = JsonHelperUtil.parseObject(productItemObj.get(key).toString());
                    if (!productNameDataObj.containsKey(StringConstant.JSON_DATA)) {
                        continue;
                    }
                    productNameDataObj = productNameDataObj.getJSONObject(StringConstant.JSON_DATA);
                    Set<String> nameKeySet = new HashSet<>(productNameDataObj.keySet());
                    for (String nameKey : nameKeySet) {
                        // 产品名称
                        if (Objects.equals(nameKey, ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr())) {
                            name = productNameDataObj.getString(nameKey);
                        } else if (showAttrList.contains(nameKey) && Objects.nonNull(ProductPrintHelpEnum.getByNewAttrContact(nameKey))) {
                            ProductPrintHelpEnum helpEnum = ProductPrintHelpEnum.getByNewAttrContact(nameKey);
                            // 新旧数据各一份
                            oldData.put(helpEnum.getOldAttr(), productNameDataObj.get(nameKey));
                            oldData.put(helpEnum.getNewAttr(), productNameDataObj.get(nameKey));
                        }
                    }
                    // 新旧名称各一份，还有一份2401,text_1
                    oldData.put(ProductPrintHelpEnum.PRODUCT_NAME.getOldAttr(), name);
                    oldData.put(ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr(), name);
                    oldData.put(XbbRefTypeEnum.PRODUCT.getCode() + StringConstant.COMMA + ProductPrintHelpEnum.PRODUCT_NAME.getNewAttr(), name);

                }  else if (Objects.nonNull(ProductPrintHelpEnum.getOldAttrByNewAttr(key))) {
                    boolean notCalcFlag = Objects.equals(ProductPrintHelpEnum.INSTOCK_NUM.getNewAttr(), key) ||
                            Objects.equals(ProductPrintHelpEnum.OUTSTOCK_NUM.getNewAttr(), key) ||
                            Objects.equals(ProductPrintHelpEnum.WAIT_INSTOCK_NUM.getNewAttr(), key) ||
                            Objects.equals(ProductPrintHelpEnum.WAIT_OUTSTOCK_NUM.getNewAttr(), key) ||
                            Objects.equals(ProductPrintHelpEnum.RETURN_NUM.getNewAttr(), key);
                    if (notCalcFlag) {
                        oldData.put(ProductPrintHelpEnum.getOldAttrByNewAttr(key), productItemObj.get(key) + "(" + I18nMessageUtil.getMessage(MessageConstant.PROCESS_PRINT_LINK_DATA_CALC_NOT_PRECISE) + ")");
                        productItemObj.put(key, productItemObj.get(key) + "(" + I18nMessageUtil.getMessage(MessageConstant.PROCESS_PRINT_LINK_DATA_CALC_NOT_PRECISE) + ")");
                    } else {
                        oldData.put(ProductPrintHelpEnum.getOldAttrByNewAttr(key), productItemObj.get(key));
                    }
                }
            }
            productItemObj.putAll(oldData);
            newProductArray.add(productItemObj);
        }

        return newProductArray;
    }

    /**
     * 调整字段数据值（有些数组要转成String）
     *
     * @param productArray 产品数据
     * @param fieldAttrEntity 解释实体
     * @param productNameAttr 产品名称字段
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-04-01 22:51
     * @since v4.16.0
     * @version v4.16.0
     */
    private JSONObject adjustAttrValueByProcess(JSONArray productArray, FieldAttrEntity fieldAttrEntity, String productNameAttr) {
        if (fieldAttrEntity == null || productArray == null) {
            return null;
        }
        Integer fieldType = fieldAttrEntity.getFieldType();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (fieldTypeEnum == null) {
            // 不是子表单的跳过
            return null;
        }
        SubFormPoJo subFormPoJo = fieldAttrEntity.getSubForm();
        if (subFormPoJo == null) {
            return null;
        }
        List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
        if (items == null || items.isEmpty()) {
            // 子表单无字段跳过
            return null;
        }
        boolean isHideUnit = false;
        for (Object obj : productArray) {
            JSONObject valueObj = (JSONObject)obj;
            for (FieldAttrEntity item : items) {
                String thisAttr = item.getAttr();
                Integer thisFieldType = item.getFieldType();
                String dateType = item.getDateType();
                if (!isHideUnit && Objects.equals(thisAttr, SelectProductEnum.UNIT.getAttr()) && Objects.equals(item.getVisible(), 0)) {
                    isHideUnit = true;
                }
                if (Objects.equals(thisFieldType, FieldTypeEnum.BATCH.getType())) {
                    thisFieldType = FieldTypeEnum.COMBO.getType();
                }
                adjustAttrValueByFieldType(valueObj, thisAttr, dateType, thisFieldType);
            }
        }
        // 审批打印支持多单位
        for (Object obj : productArray) {
            JSONObject valueObj = (JSONObject)obj;
            for (FieldAttrEntity item : items) {
                if (Objects.equals(item.getAttr(), SelectProductEnum.NUM.getAttr()) && Objects.equals(item.getIsRedundant(), 0)) {
                    valueObj.put(SelectProductEnum.BUSINESS_NUM.getAttr(),valueObj.getDouble(SelectProductEnum.NUM.getAttr()));
                    valueObj.put(SelectProductEnum.BUSINESS_UNIT.getAttr(),valueObj.getString(SelectProductEnum.UNIT.getAttr()));
                    boolean isMulti = Objects.equals(valueObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr()), 1);
                    if (isMulti) {
                        JSONArray transformUnitRate = valueObj.getJSONArray(ProductConstant.TRANSFORM_UNIT_RATE);
                        String baseName = transformUnitRate.getJSONObject(0).getString(MultiUnitConstant.MULTI_UNIT_TEXT);
                        for (int i = 0; i < transformUnitRate.size(); i++) {
                            JSONObject transformUnitObj = transformUnitRate.getJSONObject(i);
                            if (Objects.equals(valueObj.getString(SelectProductEnum.UNIT.getAttr()), transformUnitObj.getString(MultiUnitConstant.MULTI_UNIT_TEXT))) {
                                Double rate = transformUnitObj.getDouble(MultiUnitConstant.RATE);
                                valueObj.put(SelectProductEnum.NUM.getAttr(), Arith.mul(rate, valueObj.getDouble(SelectProductEnum.BUSINESS_NUM.getAttr())));
                                valueObj.put(SelectProductEnum.UNIT.getAttr(), baseName);
                                break;
                            }
                        }
                    }
                    break;
                }
            }
        }
        if (isHideUnit) {
            for (int i = 0; i < productArray.size(); i++) {
                JSONObject jsonObject = productArray.getJSONObject(i);
                jsonObject.remove(SelectProductEnum.BUSINESS_UNIT.getAttr());
                jsonObject.remove(SelectProductEnum.UNIT.getAttr());
            }
        }
        // 子表单字段的关联数据
        JSONObject dataLinkInfoSub = new JSONObject();
        JSONArray newProductAttay = productArray;
        for (FieldAttrEntity item : items) {
            String thisAttr = item.getAttr();
            LinkInfoPojo linkInfo = item.getLinkInfo();
            if (Objects.nonNull(linkInfo)) {
                dataLinkInfoSub.putIfAbsent(thisAttr,linkInfo);
                if (Objects.equals(productNameAttr, thisAttr)) {
                    newProductAttay = handleProductName(productArray, productNameAttr, linkInfo.getLinkedShowAttr());
                }
            }
        }
        // 将格式化后的数据放回
        JSONObject result = new JSONObject();
        result.put(PrintConstant.ATTRLIST,newProductAttay);
        result.put("dataLinkInfo",dataLinkInfoSub);

        return result;
    }

    /**
     * 处理产品子表单的可见与不可见
     * @author jiping.yang
     * @date 2022-12-16 22:51
     */
    private void setProductSubForm(JSONObject newProduct, JSONObject data, UserVO loginUser, FieldAttrEntity fieldAttrEntity)throws XbbException{
        // 子表单相关数据
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        handlerExplainDTO.setLoginUser(loginUser);
        handlerExplainDTO.setUserId(loginUser.getUserId());
        String creatorId = data.getJSONObject(FieldTypeEnum.CREATORID.getAlias()).getString("id");
        handlerExplainDTO.setCreatorId(creatorId);
        JSONArray ownerArray = data.getJSONArray(FieldTypeEnum.OWNERID.getAlias());
        if (Objects.nonNull(ownerArray)){
            List<String> ownerId = new ArrayList<>();
            for (int x=0; x<ownerArray.size(); x++){
                JSONObject jsonObject = ownerArray.getJSONObject(x);
                ownerId.add(jsonObject.getString("id"));
            }
            handlerExplainDTO.setOwnerId(ownerId);
        }
        JSONArray coUserArray = data.getJSONArray(FieldTypeEnum.COUSERID.getAlias());
        if (Objects.nonNull(coUserArray)){
            List<String> coUserId = new ArrayList<>();
            for (int y=0; y<coUserArray.size(); y++){
                JSONObject jsonObject = coUserArray.getJSONObject(y);
                coUserId.add(jsonObject.getString("id"));
            }
            handlerExplainDTO.setCoUserId(coUserId);
        }
        Map<String, FieldAttrEntity> subFieldMap = ExplainUtil.getExplainMap(JSON.toJSONString(fieldAttrEntity.getSubForm().getItems()), null);
        JSONArray jsonArray = newProduct.getJSONArray(PrintConstant.ATTRLIST);
        if (Objects.nonNull(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                if (Objects.nonNull(jsonObject)) {
                    Iterator<String> object = jsonObject.keySet().iterator();
                    while (object.hasNext()){
                        String subAttr = object.next();
                        FieldAttrEntity subField = subFieldMap.get(subAttr);
                        if (Objects.nonNull(subField) && Objects.equals(subField.getIsOpen(), 2)) {
                            object.remove();
                            continue;
                        }
                        if (Objects.nonNull(subField) && ExplainUtil.invisibleOfScope(subField, handlerExplainDTO)) {
                            jsonObject.put(subAttr, "");
                        }
                    }
                }
            }
        }
    }

    /**
     * 调整字段数据值（有些数组要转成String）
     *
     * @param serviceArray 产品数据
     * @param fieldAttrEntity 解释实体
     * @param productNameAttr 产品名称字段
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-04-01 22:51
     * @since v4.16.0
     * @version v4.16.0
     */
    private JSONObject serviceAttrValueByProcess(JSONArray serviceArray, FieldAttrEntity fieldAttrEntity, String productNameAttr) {
        if (fieldAttrEntity == null || serviceArray == null) {
            return null;
        }
        Integer fieldType = fieldAttrEntity.getFieldType();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (fieldTypeEnum == null) {
            // 不是子表单的跳过
            return null;
        }
        SubFormPoJo subFormPoJo = fieldAttrEntity.getSubForm();
        if (subFormPoJo == null) {
            return null;
        }
        List<? extends FieldAttrEntity> items = fieldAttrEntity.getSubForm().getItems();
        if (items == null || items.isEmpty()) {
            // 子表单无字段跳过
            return null;
        }
        boolean isHideUnit = false;
        for (Object obj : serviceArray) {
            JSONObject valueObj = (JSONObject)obj;
            for (FieldAttrEntity item : items) {
                String thisAttr = item.getAttr();
                Integer thisFieldType = item.getFieldType();
                String dateType = item.getDateType();
                if (!isHideUnit && Objects.equals(thisAttr, SelectProductEnum.UNIT.getAttr()) && Objects.equals(item.getVisible(), 0)) {
                    isHideUnit = true;
                }
                if (Objects.equals(thisFieldType, FieldTypeEnum.BATCH.getType())) {
                    thisFieldType = FieldTypeEnum.COMBO.getType();
                }
                adjustAttrValueByFieldType(valueObj, thisAttr, dateType, thisFieldType);
            }
        }
        // 子表单字段的关联数据
        JSONObject dataLinkInfoSub = new JSONObject();
        JSONArray newServiceAttay = serviceArray;
        for (FieldAttrEntity item : items) {
            String thisAttr = item.getAttr();
            LinkInfoPojo linkInfo = item.getLinkInfo();
            if (Objects.nonNull(linkInfo)) {
                dataLinkInfoSub.putIfAbsent(thisAttr,linkInfo);
                if (Objects.equals(productNameAttr, thisAttr)) {
                    newServiceAttay = handleServiceName(serviceArray, productNameAttr, linkInfo.getLinkedShowAttr());
                }
            }
        }
        // 将格式化后的数据放回
        JSONObject result = new JSONObject();
        result.put(PrintConstant.ATTRLIST,newServiceAttay);
        result.put("dataLinkInfo",dataLinkInfoSub);
        return result;
    }

    /**
     * 关联服务名称处理
     *
     * @param serviceArray 产品列表
     * @param productNameAttr 产品名称attr
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-04-01 15:26
     * @since v4.16.0
     * @version v4.16.0
     */
    private JSONArray handleServiceName(JSONArray serviceArray, String productNameAttr, List<LinkedAttrPoJo> linkshowAttrList) {
        JSONArray newServiceArray = new JSONArray();
        if (Objects.isNull(linkshowAttrList) || linkshowAttrList.isEmpty()) {
            return serviceArray;
        }
        List<String> showAttrList = new ArrayList<>();
        for (LinkedAttrPoJo poJo : linkshowAttrList) {
            showAttrList.add(poJo.getAttr());
        }
        for (int i=0; i<serviceArray.size(); i++) {
            JSONObject serviceItemObj = serviceArray.getJSONObject(i);
            JSONObject oldData = new JSONObject();
            for (String key : serviceItemObj.keySet()) {
                // 产品名称字段处理
                if (Objects.equals(key, productNameAttr)) {
                    String name = "";
                    JSONObject serviceNameDataObj = JsonHelperUtil.parseObject(serviceItemObj.get(key).toString());
                    if (!serviceNameDataObj.containsKey(StringConstant.JSON_DATA)) {
                        continue;
                    }
                    serviceNameDataObj = serviceNameDataObj.getJSONObject(StringConstant.JSON_DATA);
                    Set<String> nameKeySet = new HashSet<>(serviceNameDataObj.keySet());
                    for (String nameKey : nameKeySet) {
                        // 产品名称
                        if (Objects.equals(nameKey, ServicePrintHelpEnum.SERVICE_NAME.getNewAttr())) {
                            name = serviceNameDataObj.getString(nameKey);
                        } else if (showAttrList.contains(nameKey) && Objects.nonNull(ServicePrintHelpEnum.getByNewAttrContact(nameKey))) {
                            ServicePrintHelpEnum helpEnum = ServicePrintHelpEnum.getByNewAttrContact(nameKey);
                            // 新旧数据各一份
                            oldData.put(helpEnum.getOldAttr(), serviceNameDataObj.get(nameKey));
                            oldData.put(helpEnum.getNewAttr(), serviceNameDataObj.get(nameKey));
                        }
                    }
                    // 新旧名称各一份，还有一份2401,text_1
                    oldData.put(ServicePrintHelpEnum.SERVICE_NAME.getOldAttr(), name);
                    oldData.put(ServicePrintHelpEnum.SERVICE_NAME.getNewAttr(), name);
                    oldData.put(XbbRefTypeEnum.SERVICE_PROJECT.getCode() + StringConstant.COMMA + ServicePrintHelpEnum.SERVICE_NAME.getNewAttr(), name);

                } else if (Objects.nonNull(ServicePrintHelpEnum.getOldAttrByNewAttr(key))) {
                    oldData.put(ServicePrintHelpEnum.getOldAttrByNewAttr(key), serviceItemObj.get(key));
                }
            }
            serviceItemObj.putAll(oldData);
            newServiceArray.add(serviceItemObj);
        }

        return newServiceArray;
    }


}
